Every check indexgap runs

64 checks across 8 families — 22 critical, 22 warning, 20 info. Each has its own page: what triggers it, why it is worth fixing, and the imperative fix the package hands to a person or an agent.

The list is generated from the package's own registry at build time, so it is the same set of checks the installed version runs — not a description of them.

Invented facts

The checks that compare what a page says against the data row that produced it. This is the part of the package that has no equivalent in a general site auditor, and the reason indexgap will not write page text for you: a generator that supplied the numbers could not then check them.

CheckLevelWhat it reports
unsupported-numbercriticalthe text contains numbers that are not in your data:
check-by-eyeinfonumbers that are not in your data — read these with your own eyes:
source-notewarningwhat the parser has to say aloud: the file was read as cp1251, the front matter was not recognised, a canonical cannot be parsed
still-draftcriticalstatus: … — the page is marked unfinished
brief-leftcriticala brief block or a TODO is left in the file — the page is unfinished
unfilled-slotcriticalunfilled slot
llm-leftoverwarningthe model's reply was left instead of the page text: “…”
mojibakewarningtext in the wrong encoding: “…” — saved in one encoding and read in another

Indexing and reachability

Whether a page can be found, crawled and kept in the index at all. Nothing further down this list matters on a page that fails here.

CheckLevelWhat it reports
noindexcriticalthe page is closed to indexing — unless that is deliberate, there will be no traffic
nosnippetcriticalsnippets are forbidden: the page may sit in the index, but it will not appear in AI-search answers or rich results
canonical-elsewherecriticala copy of …: the canonical points there, and that page is open in the build — as it should be if this is a variant (a print version, a second address)
orphancriticalno internal link points at this page
unreachablecriticalthe page cannot be reached from the home page by following links
broken-linkwarninglinks to pages that are not in the build: … — ……. On the live site they are 404s unless the server redirects them
deepwarning… clicks from the home page — crawlers rarely get that far
js-shellcriticalno text in the source HTML — JavaScript draws it, and AI-search crawlers do not execute JavaScript

Content quality at scale

The failures that only appear when pages are compared with each other. A single generated page always looks fine; it is the set that gives the pipeline away.

CheckLevelWhat it reports
thinwarningabout … words of text — a thin page
low-uniquenesscriticalonly … of the text is unique — the rest is template
template-skeletonwarningthe same … headings in the same order on … other pages
same-openingwarning… other pages open with the same words
near-duplicatecritical… identical to …… — the engine will keep one of them
similarinfo… similar to ……
long-paragraphinfo… paragraph(s) longer than … characters — a block like that is hard to quote whole

The fields a search engine reads first and a person sees before deciding to click. On a generated site each of these is written once, in a template, and is therefore either right everywhere or wrong everywhere.

CheckLevelWhat it reports
no-titlecriticalno title
title-shortwarningtitle is … characters
title-longinfotitle is … characters — it will be cut off in the results
duplicate-titlewarning… other pages share this title
no-descriptionwarningno meta description
description-lengthinfodescription is … characters
duplicate-descriptioninfo… other pages share this description
no-h1warningno H1 — the engine has nothing to tell what the page is about
many-h1info… H1 headings on the page, one is needed
no-headingswarningthe page has no headings
no-structureinfothe text has neither lists nor tables — structural elements raise the chance of being used in an answer
img-no-altinfo… image(s) without alt text
vague-anchorinfouninformative anchors:

hreflang and language versions

hreflang is mutual, self-inclusive and per-page — three properties a template gets wrong in three different ways. These checks validate the cluster as a whole rather than the tag in isolation.

CheckLevelWhat it reports
translations-parkedcritical… language versions are closed with noindex and a canonical to the original — parked, not published
hreflang-missingwarninga page at the same path exists in another language (…), and this one declares no alternate at all. If it is a translation, link them with hreflang; if each market has its own text, there is nothing to link
hreflang-no-selfcriticalthe cluster has no link to this page itself — without a self-reference Google treats the whole cluster as invalid
hreflang-no-returncriticalthis page links to …, and that page does not link back. A one-way link is not “partly counted” — the whole link is discarded
hreflang-bad-codewarningthe “…” alternate has an empty href
hreflang-unknown-targetinfothe alternate … is not among the parsed pages — reciprocity cannot be verified
hreflang-lang-mismatchwarningthe self-reference is declared as “…” while the page declares lang=“…”
hreflang-canonical-conflictcriticalthe canonical points at a different language version (…) — that cancels hreflang: the engine will collapse the versions instead of showing the right one
hreflang-target-blockedwarningthe alternate … is closed to indexing, or its canonical points elsewhere — the cluster points at something that will not be in the index
hreflang-static-clustercritical… pages out of … declare the same set of alternates (…) and not one of them references itself. The template prints the home page's cluster on every page — as far as a search engine is concerned there are no links between the versions at all. Fixed once, in the template.

AI search and answer extraction

AI search retrieves passages and quotes them. These checks ask whether a page contains anything that survives being lifted out of it.

CheckLevelWhat it reports
no-question-headingsinfo… of … subheadings are questions — the “question → answer” shape is quoted noticeably more often
no-answerwarningno paragraph found — there is nothing to quote
answer-shortinfothe first paragraph is shorter than … characters — not enough to stand as an answer
answer-longinfothe first paragraph is … characters — to be quoted, an answer is better kept within …
answer-preamblewarningthe first paragraph opens with a run-up, “……” — AI search quotes the answer, not the introduction
jsonld-brokenwarningthe JSON-LD block does not parse (…) — for a search engine it simply is not there
jsonld-no-typeinfothe JSON-LD block has no @type
jsonld-faq-invisiblewarning… question(s) from FAQPage are missing from the visible text — markup that does not match the page risks a manual action
no-authorinfono author or organisation is given — an E-E-A-T signal
no-dateinfono machine-readable published or updated date
ai-crawler-blockedcriticalOAI-SearchBot is closed: … (critical for the AI-search crawlers, info for training crawlers)

robots.txt

Site-level findings: one file, one fix, reported once rather than per page.

CheckLevelWhat it reports
robots-blocks-allcriticalDisallow: / for every agent except … — other search engines and AI search cannot see the site
robots-blocks-pagecriticalrobots.txt does not let the search engine into the page (rule “Disallow: …”) — it will not read the text; the links and the sitemap lead here for nothing
robots-no-sitemapinforobots.txt names no Sitemap — the line `Sitemap: https://…/sitemap.xml` costs nothing
robots-unreadablewarningrobots.txt was not read: …
no-robotsinforobots.txt was not found — not an error, but not a check either: pass its path with --robots to have it checked

Freshness

Pages whose usefulness has an expiry date, still open for indexing after it passed.

CheckLevelWhat it reports
stale-eventcriticalthe date … passed more than … days ago and the page is still open to indexing — the engine is showing people something that no longer exists. Close it with noindex, redirect to the current one, or rewrite it as a report on what happened
stale-closedinfothe date … has passed and the page is already closed to indexing — that is correct