2026-08-19 · 4 MIN

Why a deploy check should never grep the live page for a sentence you typed

— WRITING

+

2026-08-19 · 4 MIN

The last line of a deploy told me the live page was not serving the build I had just pushed. It was. The page was correct, the network was handing out the right bytes, and the red line was about a sentence I had deleted from the site myself the day before.

Here is the shape of the thing. After the site goes up, a script fetches the live page and looks for a few strings in what comes back. It is there because of a build that once shipped essentially empty: every route answered 200, and none of them contained the product. A status code tells you the server replied. It does not tell you what it replied with. So the script asks for proof of content, and StackTab's deploy asked for three strings.

One of them was the hero headline, typed into the deploy script by hand: What does your stack actually cost.

The source says yes and the page says no

That headline was replaced with one that names the trigger the product exists for. I counted the occurrences in the built output rather than in the source, and this is the whole trap in two numbers:

  • .next/server/app/index.html: 0
  • grep -r src/: 1

The one hit in source is a comment at page.tsx:299 quoting the old headline to record what replaced it. Grep the source and the check looks healthy. Load the page and the string is gone. Every deploy from that point forward would have ended in a failure line about a page that was completely fine.

Pricing catalogue table with plan tiers, monthly costs, and confirmation dates — Comparative pricing structure across service tiers and platforms, tracking update currency.

Pricing catalogue table with plan tiers, monthly costs, and confirmation dates — Comparative pricing structure across service tiers and platforms, tracking update currency.

Failing after the thing has already happened

The expensive part is the ordering. This check runs after the promote, by construction, because you cannot fetch a live page before it is live. So the failure mode is not "we caught it in time". The failure mode is a scary red line on a site that is already serving customers, and a person then spending twenty minutes proving to themselves that nothing is wrong.

A comment in the same file records what that costs when it repeats: on 2026-08-07 four consecutive deploys reported FAILED across KitGrade, BreachProbe and CiteRank, and all four had landed. Every needle passed when re-run by hand minutes later. A check that cries wolf gets ignored, and then it is not a check.

And the copy needle was never answering the question anyway. The tool is asking whether the network is serving the newest build. That same sentence was on the previous build too, so it passes happily against a stale copy.

What a needle may be

the string it looks forwhere it comes fromsurvives a copy editproves the build is the newest one
What does your stack actually cost (retired)typed by hand into the deploy scriptno, 0 hits in the built HTMLno, the same sentence was on the previous build
the tagline, lowercasedread out of src/lib/site.ts at deploy time, 2 hitsyes, it moves with the copyonly when this build changed it
rs-rows--ledgerthe class on the pricing table, 1 hityes, copy cannot move itno
rs-measuredthe class the page puts on figures the engine computed, 4 hitsyesno

The honest column is the last one. None of these prove freshness. They prove the live page is this product, rendered, which is the failure that actually happened once.

The derived row has one detail worth stealing:

NEEDLE=$(node -e '
  const src = require("fs").readFileSync("src/lib/site.ts", "utf8");
  const m = src.match(/tagline:\s*"([^"]+)"/);
  if (!m || !m[1].trim()) process.exit(1);
  process.stdout.write(m[1].toLowerCase());
') || { echo "could not read the tagline - not verifying" >&2; exit 1; }

If it cannot read the file, the deploy stops. The alternative is verifying against an empty string, which matches every page on the internet, including a blank one.

The .toLowerCase() is not decoration. The layout builds the page title by joining the product name to the tagline in lower case, so the tagline reaches the served HTML lowercased and only lowercased. Searching for it as written in the source finds nothing. I checked both forms against the built file rather than assuming: capitalised absent, lowercased present twice.

The rule is now a check that runs before any of this ships. Any deploy script here that verifies against a prose needle fails, and the exemptions are narrow: a string containing a shell variable (derived at deploy time), a URL-encoded colour, a single token such as a class or a wordmark. A sentence is never on that list.

That product is StackTab, and this is how we built it: https://stacktab.kynth.studio/?utm_source=kynth-hashnode&utm_medium=social&utm_campaign=kynth


One shipped product, taken apart, once a month. What it does, what it cost to build, what the pipeline behind it looks like, and what the numbers did — read off the repository and the live site, not written from memory. Join the list.

← All writing