== Cutdown Diagnostic Code Registry

All codes use the prefix ``CDN-``. Codes are permanently assigned — retired codes are marked ``removed`` but never reused.

=== CDN-0001 — Unclosed CodeBlock fence

| Field | Value |
|---|---|
| code | CDN-0001 |
| title | Unclosed CodeBlock fence |
| level | warning |
| trigger | A ``\`\`\``` opening fence has no matching closing ``\`\`\``` before end of document |
| recovery | Content from the opening fence to end of document is treated as CodeBlock content |
| introduced_in | 0.1.4 |
| status | active |
| owner | Language |

=== CDN-0002 — Unclosed MetaBlock fence

| Field | Value |
|---|---|
| code | CDN-0002 |
| title | Unclosed MetaBlock fence |
| level | warning |
| trigger | A ``~~~`` opening fence has no matching closing ``~~~`` before end of document |
| recovery | Content from the opening fence to end of document is treated as Meta raw content |
| introduced_in | 0.1.4 |
| status | active |
| owner | Language |

=== CDN-0003 — Unclosed MathBlock fence

| Field | Value |
|---|---|
| code | CDN-0003 |
| title | Unclosed MathBlock fence |
| level | warning |
| trigger | A ``$$$`` opening fence has no matching closing ``$$$`` before end of document |
| recovery | Content from the opening fence to end of document is treated as MathBlock formula content |
| introduced_in | 0.1.4 |
| status | active |
| owner | Language |

=== CDN-0004 — Unclosed NamedBlock

| Field | Value |
|---|---|
| code | CDN-0004 |
| title | Unclosed NamedBlock |
| level | warning |
| trigger | A ``:::name`` opening line has no matching closing ``:::`` before end of document |
| recovery | Content from the opening line to end of document is treated as NamedBlock children |
| introduced_in | 0.1.4 |
| status | active |
| owner | Language |

=== CDN-0005 — Unclosed SpoilerBlock fence

| Field | Value |
|---|---|
| code | CDN-0005 |
| title | Unclosed SpoilerBlock fence |
| level | warning |
| trigger | A ``^^^`` opening fence has no matching closing ``^^^`` before end of document (or end of the enclosing block container) |
| recovery | Content from the opening fence to the boundary is treated as ``SpoilerBlock`` children (parsed as blocks) |
| introduced_in | next |
| status | active |
| owner | Language |

=== CDN-0006 — Unclosed CommentBlock fence

| Field | Value |
|---|---|
| code | CDN-0006 |
| title | Unclosed CommentBlock fence |
| level | warning |
| trigger | A ``###`` opening fence has no matching closing ``###`` before end of document |
| recovery | Content from the opening fence to end of document is treated as ``CommentBlock`` text (opaque raw string). The same rule applies as for other opaque fences (CDN-0001, CDN-0002, CDN-0003) — container boundaries are not observable from inside an opaque block. |
| introduced_in | 0.5.0 |
| status | active |
| owner | Language |

=== CDN-0007 — Attributes on table delimiter row dropped

| Field | Value |
|---|---|
| code | CDN-0007 |
| title | Attributes on table delimiter row dropped |
| level | warning |
| trigger | A ``{...}`` block appears on a table delimiter row (the alignment row of a GFM table) |
| recovery | The ``{...}`` block is dropped. Delimiter rows are structural metadata (alignment markers) and have no AST shape to carry attributes. Trailing CommentInlines on the delimiter row are still attached to the preceding header Row's ``comments`` array (see [§4.8](/latest/#s-4-8)). |
| introduced_in | 0.5.0 |
| status | removed — as of 0.8.0 ``{attrs}`` on a header separator row claim the Table slot ([§4.8](/latest/#s-4-8)) and ``+`` rows in pipe tables are ignored entirely; no dropped-attr case remains |
| owner | Language |

=== CDN-0008 — Orphaned caption line

| Field | Value |
|---|---|
| code | CDN-0008 |
| title | Orphaned caption line |
| level | warning |
| trigger | A ``^ `` line that fails any binding condition: the immediately preceding block in the current block scope is absent or not captionable, its caption slot is already filled, or a blank line separates it from the ``^ `` line |
| recovery | The ``^ `` line is emitted as a ``Paragraph`` containing the literal text (including the ``^ `` prefix) |
| introduced_in | next |
| status | active |
| owner | Language |

=== CDN-0009 — Attribute block on caption line ignored

| Field | Value |
|---|---|
| code | CDN-0009 |
| title | Attribute block on caption line ignored |
| level | warning |
| trigger | A ``{...}`` token appears at the end of a caption line (``^ ...``) |
| recovery | The ``{...}`` token is emitted as literal ``Text`` — it does not attach to any node. Caption lines carry no attributes; the parent block's attributes are set independently. |
| introduced_in | next |
| status | active |
| owner | Language |

=== CDN-0010 — ThematicBreak text content dropped (removed)

| Field | Value |
|---|---|
| code | CDN-0010 |
| title | ThematicBreak text content dropped |
| level | warning |
| trigger | A ThematicBreak line (``---``) contains non-whitespace, non-attribute text (e.g., ``--- some text {.x}``) |
| recovery | Text between the dashes and optional ``{attrs}`` is silently discarded; ThematicBreak node is emitted normally |
| introduced_in | 0.1.4 |
| status | removed — the ``ThematicBreak`` node was deleted in 0.8.0; superseded by CDN-0016 (PageBreaker tail dropped) |
| owner | Language |

=== CDN-0011 — Orphaned scope-chain attributes

| Field | Value |
|---|---|
| code | CDN-0011 |
| title | Orphaned scope-chain attributes |
| level | warning |
| trigger | One or more ``{...}`` blocks at the front of a trailing attribute chain have no slot to claim (chain has fewer slots than ``{...}`` blocks) |
| recovery | Excess ``{...}`` blocks at the front of the chain are discarded; no AST output for them. One diagnostic per chain, however many blocks are orphaned |
| introduced_in | 0.1.4 |
| status | active |
| owner | Language |

=== CDN-0012 — Heading level out of range

| Field | Value |
|---|---|
| code | CDN-0012 |
| title | Heading level out of range |
| level | warning |
| trigger | A line begins with 10 or more ``=`` characters followed by a space (would be heading level > 9) |
| recovery | The entire line is emitted as literal ``Text``; no Section node is created |
| introduced_in | 0.1.4 |
| status | active |
| owner | Language |

=== CDN-0020 — Duplicate id attribute

| Field | Value |
|---|---|
| code | CDN-0020 |
| title | Duplicate id attribute |
| level | warning |
| trigger | A second ``#id`` or ``id=`` token appears in a ``{...}`` block after the first ``id`` claim has already been made |
| recovery | The duplicate token is dropped; the first ``#id`` or ``id=`` value is kept |
| introduced_in | 0.2.0 |
| status | active |
| owner | Language |

=== CDN-0021 — ``class=`` conflicts with ``.class`` syntax

| Field | Value |
|---|---|
| code | CDN-0021 |
| title | class= conflicts with .class syntax |
| level | warning |
| trigger | A ``class=`` token appears alongside one or more ``.classname`` tokens in the same ``{...}`` block |
| recovery | The ``class=`` token is dropped; all ``.classname`` tokens are collected into the ``class`` entry |
| introduced_in | 0.2.0 |
| status | active |
| owner | Language |

=== CDN-0022 — Duplicate custom attribute key

| Field | Value |
|---|---|
| code | CDN-0022 |
| title | Duplicate custom attribute key |
| level | warning |
| trigger | A ``key=value`` token appears more than once for the same key in a ``{...}`` block |
| recovery | All occurrences after the first are dropped; the first value is kept |
| introduced_in | 0.2.0 |
| status | active |
| owner | Language |

=== CDN-0013 — Nameless NamedBlock opener

| Field | Value |
|---|---|
| code | CDN-0013 |
| title | Nameless NamedBlock opener |
| level | warning |
| trigger | A line starts with ``:::`` but is not followed by an ``[ID_LITERAL]`` character (e.g. ``::: {.alert}``, ``:::`` alone on a non-closing line) |
| recovery | The block candidate is parsed as a Paragraph. All content including ``:::`` and any trailing ``{attrs}`` is emitted as literal text. |
| introduced_in | 0.1.5 |
| status | active |
| owner | Language |

=== CDN-0014 — Crossed inline element boundaries

| Field | Value |
|---|---|
| code | CDN-0014 |
| title | Crossed inline element boundaries |
| level | warning |
| trigger | An inline element A closes via its delimiter while an opener of a **different** inline type B (one of ``**``, ``__``, ``~~``, ``^^``, ``""``, ``''``, ``[``) was present inside A's content and emitted as literal text — and a closer for B exists in the inline stream after A's boundary. Span points to A's closing delimiter (the crossing closer). |
| recovery | Existing greedy left-to-right behavior applies unchanged. No AST change. The diagnostic is informational only. |
| introduced_in | 0.3.2 |
| status | active |
| owner | Language |

=== CDN-0015 — Invalid or empty Variable key

| Field | Value |
|---|---|
| code | CDN-0015 |
| title | Invalid or empty Variable key |
| level | warning |
| trigger | A ``{{...}}`` token contains zero characters (empty key ``{{}}``) or one or more characters that are not ``[a-zA-Z0-9._-]`` (non-``ID_LITERAL``) |
| recovery | The entire ``{{...}}`` span is emitted as literal ``Text``; no ``Variable`` node is created |
| introduced_in | 0.3.4 |
| status | active |
| owner | Language |

=== CDN-0016 — PageBreaker tail dropped

| Field | Value |
|---|---|
| code | CDN-0016 |
| title | PageBreaker tail dropped |
| level | warning |
| trigger | A top-level PageBreaker line (``---``) contains anything after the leading three hyphens — surplus hyphens, ``{attrs}``, or text (e.g., ``----``, ``--- {.x}``, ``--- some text``) |
| recovery | The tail is discarded; the PageBreaker takes effect normally (page boundary, no node). ``loc`` spans the dropped tail |
| introduced_in | 0.8.0 |
| status | active |
| owner | Language |

=== CDN-0017 — Page separator inside block container

| Field | Value |
|---|---|
| code | CDN-0017 |
| title | Page separator inside block container |
| level | warning |
| trigger | A blank-line-surrounded ``---`` line is encountered inside a block container (``ListItem``, ``TaskItem``, ``QuoteBlock``, ``NamedBlock``, ``SpoilerBlock``) |
| recovery | The line is emitted as ``Paragraph([Text("---")])``; no page boundary is created. Page separation is a top-level construct. ``loc`` spans the ``---`` line. A ``---`` glued to a preceding paragraph is ordinary content and emits no diagnostic |
| introduced_in | 0.8.0 |
| status | active |
| owner | Language |

=== CDN-0018 — Table row cell count exceeds column count

| Field | Value |
|---|---|
| code | CDN-0018 |
| title | Table row cell count exceeds column count |
| level | warning |
| trigger | A table content row or header separator has more cells than the column count fixed by the first content row ([§4.8](/latest/#s-4-8), __Table shape__) |
| recovery | The surplus cells are dropped; the row parses normally with exactly the column count of cells. Short rows are padded instead and emit nothing; a mismatched ``+`` decoration row is inert and emits nothing. ``loc`` spans the dropped cells |
| introduced_in | next |
| status | active |
| owner | Language |

=== CDN-0030 — Meta block inside block container

| Field | Value |
|---|---|
| code | CDN-0030 |
| title | Meta block inside block container |
| level | warning |
| trigger | A ``~~~`` fence opener is encountered inside a block container (``ListItem``, ``TaskItem``, ``QuoteBlock``, or ``NamedBlock``) |
| recovery | The entire raw span — including the opening ``~~~`` line, all content lines, and the closing ``~~~`` line — is emitted as a single ``Paragraph`` with literal text. No ``Meta`` node is created. |
| introduced_in | 0.2.1 |
| status | active |
| owner | Language |

=== CDN-0031 — Mark nesting depth exceeded

| Field | Value |
|---|---|
| code | CDN-0031 |
| title | Mark nesting depth exceeded |
| level | warning |
| trigger | A ``::name`` ``Mark`` opener ([§5.10](/latest/#s-5-10)) is encountered at nesting depth 9 or deeper; the maximum depth is 8 |
| recovery | The over-deep opener does not open a ``Mark``. It degrades to literal ``Text("::" + name)`` and parsing continues immediately after it; enclosing ``Mark`` nodes are unaffected and still close normally. ``loc`` spans the rejected opener |
| introduced_in | 0.10.0 |
| status | active |
| owner | Language |

== Related

- [``./diagnostics-policy.md``](/latest/policies/diagnostics-policy)
- [``./diagnostic-code-registry-policy.md``](/latest/policies/diagnostic-code-registry-policy)
- [``./versioning-policy.md``](/latest/policies/versioning-policy)
