This guide covers how to diagnose and fix failures from the npm run validate pipeline. For the full pipeline specification (step definitions, performance budgets, exception process), see the Validation Pipeline reference (DOC-00007).
Who this is for
- Implementors debugging validation failures after adding components or content.
- Developers fixing CI failures before merge.
- AI agents understanding common error patterns so generated code passes validation on the first attempt.
Running Validation
The full quality gate:
npm run validate
This runs fourteen steps in sequence through scripts/validate.mjs. All steps run, and the command ends with a summary table that lists pass/fail status plus warning/error counts for each step. The pipeline still fails overall if any step fails.
Core unit tests (npm test, currently test:static-rules) run separately from the site pipeline and are not part of npm run validate — see Validation Pipeline.
Pipeline Sequence
| # | Script | Tool | What it checks |
|---|---|---|---|
| 1 | format:check | Prettier | Code formatting consistency |
| 2 | lint | ESLint | Code quality, Astro/TS rules |
| 3 | lint:tokens | Custom script | Token naming, raw color violations |
| 4 | lint:token-overrides | Custom script | Site token override validation |
| 5 | lint:static-rules | Custom script | Source-level content quality |
| 6 | generate:tokens:check | Custom script | Fluid token drift detection |
| 7 | lint:requirements | Custom script | Requirements catalog integrity |
| 8 | lint:content-ingestion | Custom script | Content frontmatter and cross-references |
| 9 | lint:ownership | Custom script | File ownership marker validation |
| 10 | lint:doc-coverage | Custom script | Documentation coverage checks |
| 11 | astro:check | astro check | TypeScript type checking |
| 12 | build | astro build | Full production build |
| 13 | test:browsing-smoke | Playwright + preview | Homepage -> articles -> article detail smoke |
| 14 | lint:a11y:axe | axe-core + Playwright | Automated accessibility audit |
When to Use npx astro check Mid-Edit
npx astro check (the pipeline’s type-check step, runnable on its own) is safe to run at any point during development. Use it to catch type errors and frontmatter validation issues without running the full pipeline. Run the full npm run validate only when a logical set of changes is complete — not after every individual edit.
Diagnosing Failures by Step
Step 1 — format:check (Prettier)
Symptom: Pipeline fails immediately with formatting differences listed.
Diagnosis: Files do not match Prettier’s formatting rules. This is the most common failure and the easiest to fix.
Fix:
npm run format
This auto-formats all files. Re-run validation after formatting.
Common causes:
- Hand-edited files without running the formatter
- IDE auto-save with different formatting settings
- Colon-prefixed attribute shorthands (
:attr) inside Astro template expressions — Prettier’s Astro parser cannot parse these. Use full-form attributes instead.
Step 2 — lint (ESLint)
Symptom: ESLint errors with rule names and file locations.
Diagnosis: Read the specific rule violation. ESLint errors are blocking; warnings are not.
Fix: Address the specific rule. Common patterns:
| Error pattern | Typical fix |
|---|---|
no-unused-vars | Remove the unused import or variable |
@typescript-eslint/no-explicit-any | Add a proper type annotation |
| Astro-specific rule violations | Check the Astro ESLint plugin docs for the rule |
Step 3 — lint:tokens
Symptom: Raw color literals or primitive token usage flagged in component files.
Diagnosis: Components must consume semantic tokens (--st-*), never raw color values (hex, rgb, hsl, oklch, named colors) or primitive color tokens (--pt-color-*).
Fix: Replace the raw value or primitive token with the corresponding semantic token. Non-color primitives (--pt-space-*, --pt-radius-*) are allowed in component styles.
Step 4 — lint:token-overrides
Symptom: Token override errors or warnings in site style files.
Diagnosis: The script validates src/site/styles/ token files. Two check types are errors (build-blocking), two are warnings (non-blocking):
| Finding | Severity | Meaning |
|---|---|---|
| Wrong-location | Error | Token prefix does not match the file (e.g., --pt-* in semantic.css) |
| Same-tier collision | Error | Same token declared in multiple site files |
| Unknown token | Warning | Token not in core inventory — likely a typo |
| Mode completeness | Warning | --st-* overridden in one mode but not the other |
Fix:
- Wrong-location: Move the declaration to the correct file (the error message names it).
- Same-tier collision: Remove the duplicate. Decide which file should own the declaration.
- Unknown token: Fix the typo, or add
/* token:new */on the declaration line if the token is intentionally new. - Mode completeness: Add the missing declaration in the other mode file (
light.cssordark.css).
See Override Precedence (DOC-00086) for the full contract.
Step 5 — lint:static-rules
Symptom: Source-level content quality violations such as missing alt text or broken internal links.
Diagnosis: This step runs the static-rules linter against routed markdown/MDX content and .astro templates. Error-severity findings are build-blocking; warnings are informational.
Fix: Read the rule ID and file path in the output. Common rules:
| Rule | Typical fix |
|---|---|
alt/missing | Add meaningful alt text to the image |
broken-link | Fix the target path or remove the dead link |
For false positives, use inline suppression comments — see Static Rules Validation (DOC-00082) for the exception system.
Step 6 — generate:tokens:check
Symptom: Drift detected between token config inputs and generated CSS output.
Diagnosis: The fluid token generator produces CSS from config files. This step checks that the generated output in src/core/styles/generated/ and src/site/styles/generated/ matches what the config would produce. Drift means someone edited the generated file directly or changed the config without regenerating.
Fix:
npm run generate:tokens
This regenerates the CSS from config. Re-run validation after regenerating.
Step 7 — lint:requirements
Symptom: Requirements catalog validation errors — missing fields, invalid references, or schema violations.
Diagnosis: This step runs tsx scripts/validate-requirements.ts against src/core/config/requirements.catalog.ts. It checks that every requirement conforms to the schema and that cross-references (e.g., appliesTo doc IDs) resolve to real targets.
Fix: Open the requirements catalog and correct the flagged entry. Common issues:
- Invalid or missing
appliesTodoc ID (must match an existingDOC-NNNNN) - Missing required fields in a requirement entry
- Status value not in the allowed enum
Step 8 — lint:content-ingestion
Symptom: Frontmatter validation errors or broken cross-references in content files.
Diagnosis: Check the error message for:
- Missing required frontmatter fields (
title,description,docId,topic,audience,docType) - Invalid
topicvalue (must be in the collection’s topic tuple) - Duplicate
docIdacross docs - Dangling
relatedDocsreferences (aDOC-NNNNNthat does not exist)
Fix: Correct the frontmatter in the affected markdown file. For invalid topics, check the collection’s topic tuple (e.g., THEME_DOC_TOPICS in src/core/config/theme-docs-collection.ts).
Step 9 — lint:ownership
Symptom: Missing or invalid ownership markers in source files.
Diagnosis: Source files are expected to carry // CORE-OWNED or // SITE-OWNED as a top-of-file comment. This step flags files that are missing the marker or have it in the wrong location.
Fix: Add the appropriate ownership comment as the first line of the file. Use // CORE-OWNED for files in src/core/, src/lib/, and src/pages/api/. Use // SITE-OWNED for files in src/site/, src/content/, and most of src/pages/.
Step 10 — lint:doc-coverage
Symptom: Components flagged as missing documentation coverage.
Diagnosis: This step scans src/core/components/ and checks that each component has a corresponding entry in the documentation coverage mapping (accessibility-tests-mapping.ts). It is advisory — warnings do not block the build.
Fix: If you added a new component, add its documentation mapping entry. If the component is intentionally undocumented (e.g., an internal helper), add it to the exemption list.
Step 11 — astro:check (TypeScript)
Symptom: Type errors or component prop validation failures.
Diagnosis: Astro check validates both TypeScript types and component frontmatter schemas. Common patterns:
| Error pattern | Typical fix |
|---|---|
| Frontmatter type mismatch | Fix the value to match the schema in content.config.ts |
| Missing component prop | Add the required prop to the component usage |
| Import not found | Check the import path — case-sensitive on Linux |
| Type not assignable | Review the component’s prop interface |
Fix: Address the type error directly. If the error is in a content schema, check the Zod schema in src/content.config.ts.
Step 12 — build (Astro Build)
Symptom: Build fails with an error trace.
Diagnosis: Build failures catch issues that type checking misses — runtime template errors, broken route references, missing assets.
Common causes:
| Error pattern | Typical fix |
|---|---|
| Missing import | Add the import or fix the path |
| Route not found | Check src/pages/ for the expected route file |
| Template expression error | Fix the Astro template syntax |
| Content collection error | Check frontmatter against the collection schema |
Fix: Read the build error trace. The file path and line number point directly to the issue.
Step 13 — test:browsing-smoke (Rendered browsing smoke)
Symptom: The pipeline fails after build with a message such as Preview server did not start, Desktop Articles link not found in main navigation, Articles link did not become visible in mobile navigation, or No visible article links found on the articles index.
Diagnosis: The browsing smoke step protects one narrow public journey: homepage -> articles index -> article detail. It runs twice against astro preview, once at a desktop viewport and once at a mobile viewport. Failures usually mean one of four things:
- Preview startup failed or another process is already interfering with the preview port
- The homepage nav no longer exposes a visible
Articlespath at the tested breakpoint - The articles index rendered no visible article cards that link to canonical article detail pages
- The destination article page lost its visible H1 or its visible, non-empty main article content region
Fix: Read the failure message first, then check the corresponding surface:
| Failure text | Typical fix |
|---|---|
Preview server did not start | Run npm run build manually and fix the preview/build issue first |
Desktop Articles link not found in main navigation | Restore the top-level Articles link in menuConfig.mainNav |
Articles link did not become visible in mobile navigation | Restore the mobile menu path or the visible Articles label |
No visible article links found on the articles index | Ensure at least one non-draft article renders in the canonical grid |
Focused re-run:
npm run test:browsing-smoke
Step 14 — lint:a11y:axe (Accessibility)
Symptom: WCAG 2.2 AA violations reported on showcase or sample pages.
Diagnosis: The accessibility gate runs against dedicated test pages (not production content) in both light and dark mode. Each violation includes the axe rule ID, the affected element, and the page URL.
Common causes:
| Violation | Typical fix |
|---|---|
| Color contrast | Adjust the semantic token to meet 4.5:1 ratio (or 3:1 for large text) |
| Missing alt text | Add meaningful alt attribute to images |
| Missing form labels | Associate a <label> with each form input |
| Duplicate IDs | Ensure IDs are unique per page |
| Missing landmark | Wrap content in appropriate landmarks (<main>, <nav>) |
Fix: Address the specific axe rule violation. The fix must resolve the issue in both light and dark mode. For contrast violations, use semantic color tokens — fixing the token value fixes all components that use it.
Workflow Summary
- Make changes.
- Optionally run
npx astro checkmid-edit for quick type feedback. - When the logical set of changes is complete, run
npm run validate. - If a step fails, fix the issue and re-run from the beginning.
- Do not commit until validation passes.