Blog / Product

Why we will not grade a page we could not measure

Every AI visibility tool prints a number. When the measurement failed, that number is a guess wearing a lab coat, so ours refuses to appear.

A scanner has two jobs. The easy one is producing a score. The hard one is knowing when it has not earned the right to produce one.

Lantad has seven possible outcomes for a scan, and only one of them is a grade. The other six exist because a page can fail to be measurable in six distinct ways, and in every one of them the honest output is a description of what happened rather than a number that looks like knowledge. This post is about why we built it that way, and the specific bugs that taught us to.

  • graded Score and grade The crawler fetch and the browser render both succeeded and could be compared.
  • partial_no_render No grade No browser view, so Prose Parity is undefined. Access, structure and schema are still reported.
  • access_fatal No grade The URL answered with a 4xx or 5xx. Nothing else is meaningful.
  • access_challenged No grade Bot defense served a challenge instead of the page.
  • not_html No grade The URL does not serve HTML, so there is no page to parse.
  • not_publicly_scannable No grade A login or paywall stands between the crawler and the content.
  • unreadable No grade The body held almost no text to read.
The seven scan outcomes. Only the first one produces a grade.

A number is not a measurement

The temptation is obvious. A dashboard with a blank where the score should be looks broken, and a dashboard with a 32 in it looks like it worked. So most tools fill the blank. The trouble is that a score is a claim about a page, and if the page was never fetched then the claim is about nothing.

Our own worst example is in the repository as a permanent test case. On 15 July 2026 we scanned a well known Shopify storefront and it answered our plainly identified crawler with HTTP 429, too many requests. There was no HTML, the content type was not even text/html, and the render step was skipped entirely. A tool that scores that page is scoring a rate limit message.

lantad scan allbirds.com

  • fetch as LantadBot/1.0 429
  • content-type is HTML false
  • render in a real browser skipped
  • composite score null
  • grade withheld
The stored allbirds-rate-limited capture, measured 15 July 2026. Every field here is read from the fixture, not typed by hand.

What we withhold, and what we still report

Withholding a grade is not the same as reporting nothing. The distinction we draw is whether a given signal was measured from the page itself or from something outside it.

Access is measured from robots.txt, from response headers and from per crawler probes. None of that needs the body of the page, so it survives when the body does not. Prose Parity, retrievability, structure and schema are all read from the body, so when the body is an error page or a login wall they are set to null rather than scored. Getting this wrong is not theoretical: an earlier version scored structure and schema on the error page body, which is how a rate limited storefront briefly showed a structure reading of 0.385 as though it described the shop.

Scored from the wrong document

  • structure 0.385
  • schema 0
  • reads as a finding about the shop
  • actually describes a 429 message

What ships now

  • structure null
  • schema null
  • access 0, measured from headers
  • headline states the fetch failed
The same degraded scan, before and after the fix. Left is what a body derived sub-score describes when the body is an error page.

Three ways a confident number goes wrong

Each of these was a real defect in our own engine, found by auditing the honesty of the output rather than the correctness of the arithmetic. They are the reason the rule is a rule.

The first: when robots.txt returned a server error we assumed disallow, which is the cautious reading, but we also raised per crawler defects quoting a Disallow rule that did not exist. The tool was inventing evidence in order to look specific. The second: sub-scores computed on a bot defense shell leaked into the report under a headline that had deliberately withheld the grade, so the page contradicted itself. The third, and the one worth remembering: our cloaking check compared the crawler body against the browser body, and on a short page a single changing token was enough to trip it. A visitor counter or a clock could produce a public accusation that a site serves different content to AI crawlers. We now require a minimum body size before that claim can be made at all.

  • Invented a Disallow rule A robots.txt 5xx became per crawler block defects quoting a rule nobody had read. Now only the file error itself is reported.
  • Leaked sub-scores from a shell Structure and schema scored on a bot defense page sat under a headline that withheld the grade. Now nulled with the rest.
  • Accused a clock of cloaking One varying token on a short page read as serving different content to crawlers. Now gated on a minimum body size.
Three honesty defects found in our own engine, and the rule each one produced.

What you get instead of a number

When the grade is withheld the report leads with the reason, in the same place the score would have been, and states what was and was not measured. That is less satisfying than a gauge and considerably more useful, because it tells you what to fix first: a page that cannot be fetched has exactly one problem worth your attention.

The trade is deliberate. We would rather show you a blank with an explanation than a plausible number you might act on. A wrong grade does not just mislead, it sends you to fix the wrong thing.

Fetch failed

  • Crawlers cannot fetch this page: HTTP 429.
  • Everything else is moot until the URL serves content.
  • grade withheld

Fully measured

  • gymshark.com, same platform
  • composite 94.3, grade A
  • parity 0.958, access 0.9
Real headlines from two stored captures, measured 15 July 2026.

Related

See what AI can read on your site

Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.