DEV Community

linkbruno.com
linkbruno.com

Posted on

Every URL in your error messages is a promise: a 10-point checklist for links baked into software

Somewhere in a terminal right now, a developer is reading an error message like this:

Error: invalid config key "timeout_ms". See https://docs.example.dev/v2/config#timeouts
Enter fullscreen mode Exit fullscreen mode

They click it. They get a 404, because the docs were reorganised last year. The software they're running is two years old, still working, still installed, and still printing that URL.

Links baked into software are different from links on a web page. You can fix a web page with a deploy. You can't fix a URL that's compiled into version 2.3.1 of a CLI installed on thousands of laptops, embedded in a mobile app nobody updates, or written into a config file template copied into countless repos.

Every one of those URLs is a promise that will outlive your current docs structure. Here's a checklist for making promises you can keep.

Before you add a URL to code

1. Decide whether the link needs to be in the code at all.

Sometimes the most durable link is no link: a short, searchable error code instead.

Error E1042: invalid config key "timeout_ms"
Enter fullscreen mode Exit fullscreen mode

Search engines, your docs search and humans can all find "E1042" long after URLs change. Many mature tools combine both: an error code and a link built from it.

2. Use a dedicated, stable redirect path you control.

Instead of linking to the docs page directly, link to a short path designed never to move:

https://example.dev/e/E1042
https://example.dev/go/config-timeouts
Enter fullscreen mode Exit fullscreen mode

That path redirects to wherever the content lives today. When docs move, you update one redirect, and every old version of your software keeps working.

3. Keep the redirect service boring and on your own domain.

Don't use a third-party link shortener for this. If it shuts down or changes its terms, every installed copy breaks at once. Use your own domain, ideally one that isn't tied to a docs platform you might leave.

4. Never encode a version in the stable path unless you mean it.

/go/v2/config is fine if you'll maintain v2 links forever. If you'd rather point everyone at the latest relevant page, leave the version out of the stable link and let the redirect decide.

When you ship

5. Extract and list every URL in the release.

A simple search over the source and built artifacts catches most of them:

grep -rhoE 'https?://[^"'"'"' )>]+' src/ templates/ | sort -u > release-urls.txt
Enter fullscreen mode Exit fullscreen mode

Keep that list with the release. It's the inventory of promises you just made.

6. Check every URL in that list in CI.

Every URL in the release should return a 200 (after redirects) at the moment you ship. Fail the build if any don't. This also catches typos that would otherwise ship to everyone.

7. Include the less obvious places.

URLs hide in:

  • CLI --help output and man pages
  • error and warning messages
  • comments in generated config files and project templates
  • default "learn more" links in UI components
  • email templates and push notification payloads
  • package metadata (homepage, repository, bug tracker)
  • crash reporters and "report a bug" dialogs

When you change docs or domains

8. Treat the URL inventory from every supported release as a test suite.

Before restructuring docs, run all the URL lists from releases still in use, not just the current one. Every URL that would break needs a redirect first.

cat releases/*/release-urls.txt | sort -u | while read -r url; do
  code=$(curl -s -o /dev/null -L -w '%{http_code}' "$url")
  [ "$code" = "200" ] || echo "$code $url"
done
Enter fullscreen mode Exit fullscreen mode

9. Keep redirects for longer than you support the software.

People run unsupported versions for a long time, often precisely because they can't upgrade. Their error messages still deserve to lead somewhere useful. Redirects are cheap; keep them indefinitely.

10. Make the destination still make sense.

A redirect that lands on the docs homepage technically works but helps nobody. If a feature was removed, redirect old links to a short page explaining what changed and what to do instead. That page is often the most useful thing a user of an old version can find.

Two places that deserve extra care

Mobile and desktop apps. Many users never update, and app stores keep old versions running on old devices for years. Links in onboarding screens, settings pages, "terms" and "privacy" buttons, and help menus all need stable paths. A broken privacy policy link can even cause problems with store reviews, not just with users.

Hardware and printed material. Firmware, device screens, packaging, manuals and stickers carry URLs that can never be updated at all. For those, a stable redirect path on your own domain isn't a nice-to-have; it's the only way the link survives the product's lifetime.

Who owns the redirects

Write down who is responsible for the stable link paths, and make changes to them part of code review, not something edited by hand on a server. A small file in the repository, deployed like any other change, gives you history, review and an easy way to see every promise in one place.

A quick self-audit

Pick an old release of your software, one from two or three years ago, and run its URL list through the loop above. The result is a fairly honest measure of how well your project keeps its promises.

If you'd rather not build all of this yourself, checking links continuously, including the ones that live outside your current pages, is the problem we focus on at linkbruno.com.

Related reading

Where do the URLs in your software's error messages point today, and would they still work if you reorganised your docs tomorrow?

Top comments (0)