Back to Blog
IT Strategy Code Quality Web Development Australian Business

One Guard, Written Four Times

By Ash Ganda | 28 September 2026 | 8 min read

Here is a small rule that most websites need and most websites get wrong somewhere.

A page declares an image. The file might not be there — it was renamed, it was never generated, a path changed. If the page renders the declared path anyway, the visitor gets a broken-image icon and anyone sharing the page gets a social card that is a 404. So before rendering it, check the file exists and fall back to a default if it does not.

Simple. We had written it. It worked.

It existed in exactly one of the five places that needed it.

What the audit found

One template — the main blog post route — carried the guard. It checked the declared social image, and it stripped the query string before checking, because that template had previously been bitten by cache-busted filenames.

Four other templates had no guard at all: two sub-brand routes, the listing page, and the index. So did the blog post’s own hero image, in the same file that guarded its social card.

Twelve broken image references were rendering in the built output.

Nobody had removed a check. The four other templates had simply been written at different times by people solving the immediate problem in front of them, and the problem “what if the file is not there” had only ever been encountered on one route.

The detail that makes this worse than a copy-paste story

The template with the guard was the one most recently fixed. That is why it was also the only one handling the query string.

When a file is cache-busted — hero.webp?v=2, so browsers fetch the new version instead of a stale cached one — the declared path no longer matches a filename on disk. A naive existence check looks for a file literally called hero.webp?v=2, does not find it, and concludes the image is missing. A correct check strips everything from the ? before looking.

So if anyone had noticed the duplication and consolidated by copying an older template’s version, they would have shipped the wrong rule everywhere and hidden every cache-busted image on the site. The good version was the newest one, which is the opposite of the usual assumption that the original is canonical and the copies have drifted.

★ Insight ───────────────────────────────────── This is the argument against consolidating duplicated logic by picking a copy at random. Copies do not drift uniformly — the one that has been exercised hardest usually carries fixes the others never needed. Before merging N implementations into one, the question is not “which is the original” but “what does each one know that the others do not”, and the answer is normally in the edge cases each has been forced to handle. ─────────────────────────────────────────────────

The fix, and the audit that proved it

The rule now lives in one small shared module that every template imports. There is exactly one place it can be wrong, and when it changes, everything changes with it, because every template reads it rather than remembering it.

The verification is the part worth copying, because it is the only reason we can state anything with confidence. We audited the rendered output, not the source:

  • 2,296 image references across the built site: 0 broken.
  • 713 internal links: 0 broken.

Auditing the source would have told us the templates import the helper. It would not have told us whether the pages that came out the other end actually point at files that exist. Those are different questions, and only the second one is what a visitor experiences.

Two more defects the same audit turned up

Checking links properly surfaced two things that had nothing to do with images.

Structured data pointing at a domain that no longer resolves. Four older posts carried machine-readable markup whose identifiers, publisher URL, article URL and image URL all pointed at two domains that fail DNS entirely — not a 404, a hostname that does not resolve.

The tempting fix was to swap in the working domain for those brands. That would have been worse. Those addresses answer every URL with the homepage, so the markup’s image field would have returned a web page where search engines expect an image file. A loud failure would have become a silent one, and silent failures in structured data are how a site quietly loses its rich results. The content actually lives on this site, so the identifiers now point here — verified returning 200 with the correct content type — and only the brand homepage keeps its own address, because that is a real page.

Two links to pages that do not exist. Two posts linked to division pages on the parent site. Only three of the five division pages have been built; both links were 404s. Repointed at the live brand pages.

Neither of these was visible from the source. Both required following the links and looking at what came back.

How the duplication happened, which is not carelessness

Worth stating plainly, because the instinct after finding this is to assume somebody was sloppy, and that reading produces the wrong fix.

The guard was not copied four times and allowed to drift. It was written once, in the template where the problem had actually occurred, and the other four templates were written before or after by people who had never hit it. There was nothing to copy at the time and nothing to notice afterwards, because a missing check leaves no trace in the file that lacks it.

That is the general shape of this defect class: the duplication is not the cause, it is the symptom. The cause is that a rule which applies to five places was only ever expressed in the one place it was learned.

Which suggests a cheap habit rather than a process. When you fix something with a guard, ask one question before closing it: where else is this rule needed? Not “where else did I copy this code” — the code may not exist elsewhere yet. Where else does the same situation arise. Usually the answer takes thirty seconds and is longer than one.

What to check on your own site this week

Four checks, in order of how often they turn something up.

  1. Does your site render a declared image without checking it exists? Almost every content-driven site does this somewhere. The symptom is a broken-image icon on one page and a wrong social card when it is shared.
  2. If you cache-bust filenames, does your existence check strip the query string? If not, the check reports every cache-busted image as missing, which is the failure that looks like the fix working.
  3. Does your structured data point anywhere that no longer resolves? Old markup outlives the domains it was written against, and nothing on the page will tell you.
  4. Audit the built site, not the source. Count image references and links in what actually gets served, and check each one returns a 200 with the right content type. A source-level audit and a rendered audit answer different questions, and only the second one matches what your visitors get.

The general rule underneath all four: two independent copies of one rule have no way of telling you when they have stopped agreeing. There is no error, no warning, no failing test — just a growing gap between what one file assumes and what another does, found only when something downstream finally disagrees.


Cloud Geeks runs cloud infrastructure and IT support for Australian small businesses. Websites are built by our sister brand Cosmos Web Tech, apps by Awesome Apps, and the group is Ganda Tech Services.

Ready to upgrade your IT and cloud setup?

Let's talk about cloud, infrastructure, or cybersecurity. We help Sydney SMBs cut hosting costs, harden their stack, and stop firefighting.

Bella Vista, Sydney