# Troubleshooting

> What every vage check finding means and how to fix it, from broken links and missing descriptions to unapproved links and page errors.

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.
