Finding Codes Reference
Every issue detected by Zenzic is tagged with a canonical finding code (Zxxx). This page is the quick-reference cheat sheet — severity, penalty, exit code, and the essential remediation path for every diagnostic signal.
Tier Model
Zenzic organises diagnostics into four operational tiers:
| Tier | Ownership | Format | Scope |
|---|---|---|---|
| Core | Zenzic | Zxxx | Built-in scanners and system findings |
| Governance | Zenzic | Z6xx | Opt-in policy checks ([governance]) |
| Plugin | Third-party | <plugin-id>:<code> | External entry-point rules |
| Custom | Project local | ZZxxx | [[custom_rules]] declared in TOML |
Stability Contract
The code registry is governed by immutable contract surfaces:
FROZEN_CODES: codes that cannot be renumbered or semantically changed without architecture-level approval.NON_SUPPRESSIBLE_CODES: security codes that cannot be silenced inline.PLUGIN_FORBIDDEN_EXITS: plugins are forbidden from emitting Exit 2/3 (reserved for core security semantics).
Each code has a permanent anchor. You can link directly to a specific code using https://zenzic.dev/docs/reference/finding-codes#z101.
Category Overview
| Category | Range | Purpose | Default Severity | Suppressible? |
|---|---|---|---|---|
| Z0xx | Migration & Compatibility | Engine deprecation; migration guidance | error | ❌ No (fatal abort) |
| Z1xx | Link Integrity | Broken, empty, circular links; orphaned pages; path issues | error/warning/info | ✅ Yes |
| Z2xx | Security (credential scanner) | Secret detection; path traversal; security incidents | warning/security_breach/security_incident | 🔒 Never |
| Z3xx | Reference Integrity | Dangling/duplicate reference definitions | error/warning | ✅ Yes |
| Z4xx | Structure | Directory indexes, orphan pages, missing alt text, config assets | info/warning | ✅ Yes |
| Z5xx | Content Quality | Placeholder text, short content, snippet validation, regressions | warning/error | ✅ Yes |
| Z6xx | Governance | Brand obsolescence, translation parity (opt-in) | warning | ✅ Yes |
| Z9xx | Engine & System | Rule execution errors, timeouts, system-level diagnostics | error/warning | ✅ Yes |
Suppress a finding on a specific line with a format-aware comment on that same line.
Markdown (.md): <!-- zenzic:ignore: Zxxx -->
MDX (.mdx): {/* zenzic:ignore: Zxxx */}
See Suppression Policy for the full reference.
Exit Code Contract
| Exit Code | Meaning | Suppressible? |
|---|---|---|
| 0 | All checks passed (or suppressed via --exit-zero) | — |
| 1 | Errors and warnings detected; use --strict to promote warnings | ✅ Yes |
| 2 | Security breaches (Z201, Z204). Never suppressed | ❌ Never |
| 3 | Security incidents (Z203 PATH_TRAVERSAL_FATAL). Never suppressed, even with --exit-zero | ❌ Never |
Z0xx — Migration & Compatibility
Z000: UNSUPPORTED_ENGINE
Severity: error (fatal abort) · Penalty: none · Exit: 1 · Suppressible: No
Fatal configuration error: the adapter factory encountered a deprecated or removed engine alias in .zenzic.toml. Execution stops before any scan begins — Z000 does not appear in --format json output.
Fix:
- Open
.zenzic.tomland setengine = "standalone"(or"mkdocs","docusaurus","zensical"). - Remove any legacy engine alias.
Z1xx — Link Integrity
Z101: LINK_BROKEN
Severity: error · Penalty: −8.0 pts (Structural) · Exit: 1 · Suppressible: Yes · ↗ Gallery
A relative link points to a resource not found in the Virtual Site Map. The file may be outside docs_dir scope or matched by an exclusion rule.
Fix:
- Verify the physical file exists.
- Correct the relative path (e.g.
../folder/target.md). - Confirm the file is not matched by
ignored_patternsin config.
Z102: ANCHOR_MISSING
Severity: error · Penalty: −5.0 pts (Structural) · Exit: 1 · Suppressible: Yes · ↗ Gallery
The link target file exists (Z101 passes), but the specific HTML anchor (e.g. #setup) is absent from the target file's header registry. Zenzic parses all headings and explicit <a id="..."> tags during Pass 1.
Fix:
- Check the target file's heading text and verify the anchor slug.
- Ensure Kebab-case slugification matches the Markdown engine (Docusaurus: lowercase, spaces → hyphens).
- Use
{#id}or<a id="id"></a>for custom IDs.
Z103: ORPHAN_LINK
Severity: error · Penalty: 0.0 pts · Exit: 1 · Suppressible: Yes · ↗ Gallery
The link target exists in the VSM but is not reachable through any navigation structure (sidebar/nav). Users can reach it only by direct URL.
Fix:
- Add the file to
nav(MkDocs) orsidebars.ts(Docusaurus). - If the hidden page is intentional, suppress with
<!-- zenzic:ignore: Z103 -->.
Z104: FILE_NOT_FOUND
Severity: error · Penalty: −8.0 pts (Structural) · Exit: 1 · Suppressible: Yes
Low-level filesystem error: the engine could not open a file referenced by a link. Also fires as a slug-mismatch variant in Docusaurus: an absolute link targets a project-owned route prefix (e.g. /blog/) but the exact slug does not exist in the VSM — the most common cause is a slug: frontmatter field that differs from the URL used in the link.
blog/post.mdx:12: '/blog/zenzic-v070' not found in the site map
💡 Did you mean: '/blog/zenzic-v070-release/'?
Fix:
- Verify no concurrent process is modifying
docs/during the scan. - Check
docs_diris correct and the file path is absolute relative to the repo root. - (Slug-mismatch) Run
zenzic inspect routes --kind physicalto list all canonical slugs in the VSM. Update the link to match the exact frontmatterslug:.
Z105: ABSOLUTE_PATH
Severity: error · Penalty: −2.0 pts (Structural) · Exit: 1 · Suppressible: Yes · ↗ Gallery
An absolute filesystem path (e.g. C:\Docs\page.md or /home/user/docs/page.md) breaks documentation portability. Project-owned URL prefixes (/blog/, /docs/) are exempt from Z105 but still checked via VSM lookup (a missing slug raises Z104 instead).
Fix:
- Convert to a relative path from the current file's directory.
- Use
@site/or engine-specific aliases where supported. - If you received Z104 on an absolute
/blog/link, see Z104 remediation above.
Z106: CIRCULAR_LINK
Severity: info · Penalty: 0.0 pts · Exit: 0 · Suppressible: Yes (informational only, --show-info)
A set of links forms a directed cycle (A → B → A). This is a structural telemetry signal — it does not block the Quality Gate or reduce the DQS.
Fix: Review the content flow; consider replacing one link with a "See Also" section. No action required if the cycle is intentional.
Z107: CIRCULAR_ANCHOR
Severity: warning · Penalty: −1.0 pt (Structural) · Exit: 1 · Suppressible: Yes
A link of the form [text](#anchor) resolves to a heading on the same page — a self-loop that navigates the reader to exactly where they already are. Distinct from a ToC entry (which links forward to a lower anchor on a long page).
Fix:
- Replace
[text](#anchor)with plain prose if no navigation is intended. - Or link to the concept on a different page.
Z108: EMPTY_LINK_TEXT
Severity: error · Penalty: −1.0 pt (Structural) · Exit: 1 · Suppressible: Yes · ↗ Gallery
Inline Markdown link or collapsed reference link has empty or whitespace-only visible text — e.g. [](./page.md), [ ](./page.md), [][ref]. Breaks screen reader accessibility and semantic indexing simultaneously.
Fix:
- Add descriptive link text:
[Documentation](./page.md). - Remove the link entirely if the destination is not yet known.
Z109: EXTERNAL_LINK_BROKEN
Severity: error · Penalty: −3.0 pt (Structural) · Exit: 1 · Suppressible: Yes · ↗ Gallery
An external URL returned an HTTP error status code (e.g. 404, 500) or was completely unreachable due to a connection timeout or DNS resolution failure during scan.
Fix:
- Check the target URL in a web browser.
- Correct the URL if misspelled, or remove the link if the destination has ceased to exist.
Z2xx — Security (credential scanner)
Z201: CREDENTIAL_SECRET
zenzic:ignore: Z201 is silently rejected. The credential scanner fires unconditionally on every line. ↗ Gallery
Severity: security_breach · Penalty: DQS collapses to 0/100 · Exit: 2
The credential scanner uses deterministic pattern matching (e.g., RE2) to detect known structural secrets (like AWS keys or GitHub tokens) without exponential backtracking, rather than relying on high-noise entropy checks. Speculative Base64 decoding is also applied — encoded tokens that decode to credential patterns are flagged.
Fix:
- IMMEDIATE: Rotate the leaked credential — it is compromised.
- Remove the secret from the file.
- Purge the git history using
git-filter-repo. - Use placeholders such as
YOUR_API_KEYin documentation examples.
Z202: PATH_TRAVERSAL
zenzic:ignore: Z202 is silently rejected. ↗ Gallery
Severity: error · Penalty: DQS collapses to 0/100 · Exit: 1
The Path Traversal Guard intercepts any relative links attempting to escape the documentation root (e.g. ../.env). A relative path uses .. segments to escape the docs/ boundary, potentially exposing private repository files.
Fix:
- Move the target asset into the
docs/orstatic/hierarchy. - If you must reference an external file, use a symbolic link (if permitted) or a literal absolute URL.
Z203: PATH_TRAVERSAL_FATAL
zenzic:ignore: Z203 is silently rejected. Distinct from Z202: targets OS directories (/etc/, /root/) signalling supply-chain compromise.
Severity: security_incident · Penalty: DQS collapses to 0/100 · Exit: 3
Path traversal detected targeting restricted OS directories (e.g. /etc/, /root/). Cannot result from a legitimate documentation workflow — presence indicates template injection, a compromised toolchain, or a malicious commit.
Fix:
- Investigate the source file for malicious intent or supply-chain compromise.
- Remove all absolute paths referencing host-system locations.
- Audit your CI pipeline for injection vectors.
Z204: FORBIDDEN_TERM
zenzic:ignore: Z204 is silently rejected. Source: forbidden_patterns in .zenzic.local.toml (git-ignored). ↗ Gallery
Severity: security_breach · Penalty: DQS collapses to 0/100 · Exit: 2
The Privacy Gate detected a confidential project term (internal code-name, staging hostname, team alias) configured in .zenzic.local.toml. Matching is case-insensitive verbatim substring — no regex. Run zenzic init to scaffold .zenzic.local.toml (auto-added to .gitignore).
| Layer | Source | Scope | Severity |
|---|---|---|---|
| Z204 Privacy Gate | forbidden_patterns in .zenzic.local.toml (git-ignored) | Private terms — code-names, staging hosts | Exit 2 (Critical) |
| Z601 Brand Guard | [governance].brand_obsolescence in .zenzic.toml | Deprecated brand terms | Exit 1 (Quality) |
Fix:
- Remove or generalise the forbidden term.
- If the term is legitimately public, remove it from
forbidden_patterns. - Verify
.zenzic.local.tomlis in.gitignore.
Z3xx — Reference Integrity
Z301: DANGLING_REF
Severity: error · Penalty: −4.0 pts (Navigation) · Exit: 1 · Suppressible: Yes · ↗ Gallery
A reference-style link ([my link][ref]) exists but its definition ([ref]: http://...) is missing. Most renderers silently degrade the link to plain text. Ensure your Markdown formatter (like Prettier or Markdownlint) does not inadvertently remove unused reference definitions during an automated pass, which can cause downstream references to dangle.
Fix:
- Add the missing definition at the bottom of the Markdown file.
- Check for typos in the reference ID.
Z302: DEAD_DEF
Severity: warning · Penalty: −1.0 pt (Navigation) · Exit: 1 · Suppressible: Yes · ↗ Gallery
A reference definition exists but no link in the file uses it. Harmless for readers but creates maintenance debt.
Fix: Remove the unused definition, or update a link to use this reference.
Z303: DUPLICATE_DEF
Severity: warning · Penalty: −3.0 pts (Navigation) · Exit: 1 · Suppressible: Yes · ↗ Gallery
Multiple definitions exist for the same reference ID. CommonMark specifies that the first definition wins, but this ambiguity should be resolved for deterministic cross-engine rendering.
Fix: Ensure each reference ID has exactly one definition; consolidate duplicates into a single canonical reference.
Z4xx — Structure
Z401: MISSING_DIRECTORY_INDEX
Severity: info · Penalty: none (structural hint) · Exit: 0 · Suppressible: Yes
A documentation directory has no index.md or README.md. The directory URL may return 404 or a raw listing depending on the build engine.
Fix: Create index.md in the flagged directory with a brief section overview.
Z402: ORPHAN_PAGE
Severity: warning · Penalty: −4.0 pts (Navigation) · Exit: 1 · Suppressible: Yes · ↗ Gallery
A file exists in docs/ but is not reachable from any navigation menu. The documentation equivalent of dead code.
Fix:
- Add the file to
nav(MkDocs) orsidebars.ts(Docusaurus). - Delete the file if it is a leftover artifact.
Z403: MISSING_ALT
Severity: warning · Penalty: none (accessibility warning) · Exit: 1 · Suppressible: Yes · ↗ Gallery
An image has no alt text, degrading screen reader accessibility and SEO.
Fix: Add descriptive text: . Avoid generic labels like "image" or "screenshot".
Z404: CONFIG_ASSET_MISSING
Severity: warning · Penalty: none (configuration integrity warning) · Exit: 1 · Suppressible: Yes
The build engine's main configuration (e.g. docusaurus.config.ts) references a logo or favicon that does not exist at the specified path. The failure is global: every page in every locale ships without the branding asset.
Fix:
- Check
favicon:orlogo.src:paths in your config file. - Ensure the asset is physically present in
static/(Docusaurus) ordocs/(MkDocs).
Z405: UNUSED_ASSET
Severity: warning · Penalty: −3.0 pts (Governance) · Exit: 1 · Suppressible: Yes
An image or asset file in the repository is never referenced by any Markdown file. "Dark Assets" bloat the repository and build artifacts silently.
Fix:
- Delete the unused file.
- Or reference it in a documentation page where appropriate.
Z406: NAV_CONTRACT
Severity: error · Penalty: −2.0 pts (Governance) · Exit: 1 · Suppressible: Yes
A conflict between the physical file structure and the engine's navigation config. For MkDocs: a nav entry pointing to a path that no physical file activates. For Docusaurus: an extra.alternate link absent from the VSM.
Fix:
- Align the nav path in your config with the physical file path.
- Run
zenzic check allto verify the fix across the VSM.
Z5xx — Content Quality
Z501: PLACEHOLDER
Severity: warning · Penalty: −2.0 pts (Content) · Exit: 1 · Suppressible: Yes · ↗ Gallery
Placeholder strings (TODO, FIXME, [INSERT IMAGE HERE]) committed to production documentation signal incomplete work.
Fix: Replace the placeholder with actual content, or remove it until the content is ready.
Z502: SHORT_CONTENT
Severity: warning · Penalty: −1.0 pt (Content) · Exit: 1 · Suppressible: Yes · ↗ Gallery
A page contains fewer than 50 words of rendered prose (frontmatter, MDX comments, and HTML comments excluded). A page below this threshold cannot contain the semantic components necessary to answer a reader's question.
Fix: Expand the page, or combine it with a related page.
Z503: SNIPPET_ERROR
Severity: error · Penalty: −10.0 pts (Content — highest single-occurrence penalty) · Exit: 1 · Suppressible: Yes · ↗ Gallery
The Snippet Guard identified a syntax error in a fenced code block marked with a language tag. The reported line number is absolute — relative to the source file, not to the start of the snippet.
Fix:
- Correct the syntax within the code block.
- For intentionally broken examples, use
```textto bypass validation.
Z505: UNTAGGED_CODE_BLOCK
Severity: warning · Penalty: −1.0 pt (Content) · Exit: 1 · Suppressible: Yes · ↗ Gallery
A fenced code block has no language specifier. Syntax highlighters, the Snippet Guard (Z503), and screen readers cannot process it. Docusaurus metadata (e.g. ```python title="file.py" showLineNumbers) is fully supported and never flagged.
Fix: Add a language tag: ```python, ```bash, ```toml. For display-only blocks, use ```text or ```plaintext.
Z6xx — Governance
Z601: BRAND_OBSOLESCENCE
Severity: warning · Penalty: −2.0 pts (Governance) + Escalation · Exit: 1 · Suppressible: Yes · ↗ Gallery
A deprecated release name or brand identifier appears in a scanned file. Configured via [governance].brand_obsolescence in .zenzic.toml. CHANGELOG files are exempt by default (obsolete_names_exclude_patterns).
Governance Escalation: Beyond 10 total Z6xx occurrences, an exponential multiplier applies: deduction × 2^(excess / 5), capped at the 25-pt tier ceiling.
Fix:
- Update the text to the active release name.
- For intentional historical references in
.md: append<!-- zenzic:ignore: Z601 -->. - For
.mdxfiles: append{/* zenzic:ignore: Z601 */}. - To exempt a file pattern entirely, add it to
obsolete_names_exclude_patternsin.zenzic.toml.
Z602: I18N_PARITY
Severity: warning · Penalty: none (bilingual integrity check) · Exit: 1 · Suppressible: Yes · ↗ Gallery
A translation mirror is missing, or the frontmatter of a translated file diverges from the canonical base (sidebar_position, sidebar_label, title). Two locales with different frontmatter produce asymmetric navigation graphs.
Fix:
- Create the missing translation at
i18n/<locale>/docusaurus-plugin-content-docs/current/<path>. - Copy the base-language frontmatter block and translate the values — do not add or remove keys.
- For intentional asymmetry, suppress with
{/* zenzic:ignore: Z602 */}on the frontmatter block.
Z9xx — Engine & System
Z901: RULE_ENGINE_ERROR
Severity: error · Penalty: none (system-level) · Exit: 1 · Suppressible: Yes
An unhandled exception in a core rule or plugin. Zenzic's fail-visible principle converts silent crashes into explicit Z901 findings so the partial result is auditable.
Fix: Check the CLI output for a Python traceback. Report the issue at https://github.com/PythonWoods/zenzic/issues.
Z902: RULE_TIMEOUT
Severity: error · Penalty: none (system-level) · Exit: 1 · Suppressible: Yes
A rule exceeded the execution time limit (default > 30s). Almost always caused by catastrophic backtracking in a custom regex — a ReDoS risk that can also silently disable a security gate.
Fix:
- Review custom regex patterns in
.zenzic.toml. - Simplify patterns: avoid nested quantifiers like
(a+)+. - Use non-backtracking alternatives where possible.
Z906: NO_FILES_FOUND
Severity: note · Penalty: none · Exit: 0 · Suppressible: Yes (informational)
No .md / .mdx files found in the resolved docs_root after all exclusion layers. Suppressed in machine-output formats (json, sarif).
Fix:
- Verify
docs_dirin.zenzic.toml(or--docs-dir) points to the correct directory. - If the directory is intentionally empty, Z906 can be safely ignored — it exits 0.
Reserved Codes (Inactive)
The codes in this section are defined in the Zenzic registry and reserved for engine implementations. They are not emitted at runtime and have no impact on the Deterministic Quality Score.
Z111: VIRTUAL_ROUTE_BROKEN
Severity: error (reserved) · Engine: Docusaurus
A link targets a virtual route URL (e.g. /blog/tags/react/) that was never generated because no blog post carries that tag value in tags: frontmatter. Distinct from Z101: the URL is structurally valid, but no content source activates it.
Fix: Add the tag to the relevant posts, or update the link to target a tag that is actually generated. For forward-looking links, suppress temporarily with {/* zenzic:ignore: Z111 */}.
Z113: AUTHOR_KEY_COLLISION
Severity: error (reserved) · Engine: Docusaurus
Two or more authors.yml files declare the same author key. Docusaurus merges silently by priority, creating a hidden configuration dependency.
Fix: Identify the colliding key, keep the canonical definition, rename the duplicate, and update all blog posts that reference the renamed key.
Z114: LARGE_PAGINATION_SET
Severity: info (reserved) · Engine: Docusaurus
The blog plugin would generate more than 200 paginated index pages. Informational — not blocking.
Fix: Increase postsPerPage in docusaurus.config.ts or enable archiveBasePath to offload historical posts.
Z504: QUALITY_REGRESSION
Severity: warning (reserved)
Emitted by zenzic diff when the current DQS is lower than the saved baseline (.zenzic-score.json). Not itself weighted into the score (that would be circular); it identifies which commit introduced a regression.
Fix: Run zenzic score to see the breakdown by category, fix the underlying findings that caused the drop, then run zenzic score --save on main to update the baseline.
Historical Code Remap
| Deprecated Code | Active Code | Notes |
|---|---|---|
Z903 | Z405 | Canonical remap for UNUSED_ASSET. |
Z904 | Z406 | Canonical remap for NAV_CONTRACT. |
Z905 | Z601 | Canonical remap for BRAND_OBSOLESCENCE. |
Z907 | Z602 | Canonical remap for I18N_PARITY. |
Historical identifiers remain valid only as historical references in migration prose. Active findings and section anchors always use the canonical codes listed in this matrix.
Suppressing Diagnostics
See Suppression Policy for inline suppression syntax (
zenzic:ignore), the Suppression Debt model, and the--auditoverride.