Troubleshooting
Every finding, explained.

Each vage check finding has a rule name, the page, and the file to fix. Errors stop the build from deploying; warnings don't.

Page and build problems

Rule What it means How to fix it
page-error A page couldn't be built: invalid frontmatter, a field its layout doesn't allow, or a layout that crashed Read the message: it names the field or the layout error. The rest of the site is still checked.
frontmatter-empty A frontmatter value came out empty Usually a comma or colon inside { }. Wrap the text in quotes: { q: "Is it free, really?" }
config A setting needs attention, such as site still being https://example.com Set your real domain in vage.config.ts

Links and files

Rule What it means How to fix it
link-broken A link points to a page or file that doesn't exist, or to a draft Fix the address, publish the draft, or add a redirect
link-trailing-slash A link would redirect, e.g. /about Use /about/
asset-missing An image, script or stylesheet isn't in the build Put the file in public/ with that path
redirect-target A redirect points to a page that doesn't exist Fix the target in redirects
unsafe-url A link, image or form uses a script URL (javascript:), which runs code on your site Use a normal https: or /path/ address

Search and sharing

Rule What it means How to fix it
title A page has no title, or more than one Every page needs one title in frontmatter, and the layout must write one <title>
meta-description No description for search results Add description to the frontmatter
canonical More than one canonical link, a relative one, one pointing to an unpublished page, or (warning) one pointing to another site Set site in the config and check any canonical: in frontmatter. A canonical to another website hands that page's ranking to it.
jsonld Structured data is invalid Fix the JSON-LD your layout writes
jsonld-article Article data is missing fields Google recommends Add author and datePublished, but only real values
robots-blocks-all robots.txt blocks every crawler while pages are meant to be indexed Check seo.robots in your config

Accessibility

Rule What it means How to fix it
html-lang The page doesn't declare its language Set lang in the config and write <html lang> in the layout
img-alt An image has no alt text Describe the image: ![What it shows](/images/x.jpg)
img-dimensions An image has no width and height Images in public/ get them automatically; add them to images written in layouts
link-text A link has no text a screen reader can announce Add link text or an aria-label

Spam protection

Rule What it means How to fix it
link-unapproved A link goes to a website that isn't in links.lock.json If you added it on purpose: npx vage links approve <domain>. If you didn't, remove it and check the page's history.
links-lock-missing There's no links.lock.json (an error when outboundLinks is "require") Review npx vage links, then npx vage links approve --all, or restore the file from git
link-hidden A link is hidden from visitors but visible to search engines Remove it, or make it visible. Hidden external links are a classic sign of a hack.
spam-pattern The page contains words common in injected spam If you didn't write them, check the page's history

Analytics and security headers

Rule What it means How to fix it
analytics-event An element uses an event or parameter not declared in the config Declare it under the analytics integration's events
analytics-duplicate Google's tag loads more than once Remove the tag from your layout, or the integration from the config
csp-inline-handler An onclick="…"-style handler, which the security policy blocks Use addEventListener in a script file

Common errors outside checks

  • "Port … is already in use": you chose a port with --port that another program is using. Stop that program, or pick another port. Without --port, the dev server finds a free port by itself.
  • "Confirmation required": a deploy or links approve ran without a terminal. Review with --dry-run, then re-run with --yes.
  • A deploy refuses because of wrangler.jsonc: the file names a different Worker, or doesn't serve dist/. Make the names match and set assets.directory to "dist".
  • HTTP 431 in the browser on localhost: your browser sends too many cookies to localhost. Use http://127.0.0.1:<port>/ instead.

Start with one command.
You'll have a site running in a minute.

npm create vagejs@latest my-site

Read the docsUse it with your AI assistant