·3 min read·Mounaji Studio

A page can be down without returning a single error

Our contact form answered, looked right and sent nothing. Two indexed routes returned 200 and were empty. No uptime monitor catches that, because nothing fails — what is missing is the last mile.

engineeringtestingweb

Uptime monitoring answers one question: did the server respond? It is a good question, and it is not the one your customers are asking. They are asking whether the thing they came to do actually happened.

We found the gap in our own site, which is the least comfortable place to find it.

Three failures that all returned 200

The contact form did not send anything. The "Contact" link in our navigation pointed at a page built from an untouched UI template: four inputs with no state and no name attribute, and a "Submit" button with no submit handler. It rendered perfectly. It validated nothing, posted nothing, and told the visitor nothing was wrong — because from the browser's point of view, nothing was.

Two indexed routes were empty. One was 587 lines of code, roughly 470 of them commented out, which rendered an empty container four viewports tall. It sat in our sitemap at priority 0.9 with five links pointing to it from the footer. The other contained the words "Web Development" inside a seven-viewport div. Both returned 200. Both were in Google's index.

Five icons 404'd on every page load. The document head and the web manifest asked for apple-touch-icon.png, two favicons and two Android icons. None of the five files existed. Every visit to every page fired five failed requests, and the page still rendered fine.

Why status codes miss this

A status code describes the transport, not the transaction. 200 OK means the server found something to send. It says nothing about whether that something does its job.

The pattern generalises past web pages:

  • A webhook endpoint that returns 200 and drops the payload.
  • A checkout that shows a confirmation screen before the charge settles.
  • A form that posts successfully to an email service whose template was deleted.
  • A background job that exits zero after catching the error it was supposed to report.

In each case the monitoring is green, the logs are quiet, and the work is not happening. The failure mode is not an error — it is an acknowledgement mistaken for a result.

What to check instead

The useful question is not "did it respond" but "did the effect happen", and the effect is almost always somewhere other than the response.

For each path that matters, name the observable effect and check that:

Path Weak check Real check
Contact form Page returns 200 A message lands in the inbox
Route exists Status code Read the <title> and a known string from the body
Asset referenced File is in the repo Request the URL the HTML actually emits
Background job Exit code 0 The row it was supposed to write is there

The <title> check is worth dwelling on. We list seven products and two games on our site, each linking somewhere live. Two .vercel.app subdomains we assumed were ours answered 200 while serving the stock "Create Next App" page. The status code said the link was fine. Reading the title said it was not.

The cheap version of this

You do not need a test suite to close most of the gap. You need one assertion per critical path that names the effect:

  • Submit the real form from a real browser once per deploy, and check the inbox.
  • For every URL in your sitemap, fetch it and assert a string that only that page contains.
  • For every asset referenced in your HTML head, fetch it and assert a non-zero body.

Each of those takes minutes to write. All three together would have caught everything above, months earlier.

The rule we took from it: a check that can only go green is not a check. If you cannot describe the state of the world that would make your test fail, the test is measuring the transport, and the transport was never the part you were worried about.

Chat with us