---
title: Diagnostics
description: Every DS-* code, what triggers it, and whether it fails the build.
---

Content problems are reported as `DS-*` codes with a severity. **Errors fail
`reed check` and `reed build`. Warnings do not**, unless you escalate them.

Three families: `DS-S*` structure, `DS-D*` design and density, `DS-A*` accessibility.

## Escalating warnings

<ParamField name="--strict-components" type="flag">
  Escalates `DS-D*` warnings to errors.
</ParamField>

<ParamField name="--strict-tokens" type="flag">
  Escalates every warning that is not `DS-D*`.
</ParamField>

The two cover disjoint sets and compose — pass both to fail on everything.

## `DS-S*` — structure. Always errors.

| Code | Triggered by |
|---|---|
| `DS-S01` | A component has a child its contract disallows — e.g. anything but `Card` inside `CardGroup`. The message lists the permitted children. |
| `DS-S02` | Fewer element children than the contract's minimum — e.g. a `Steps` with one `Step`. |
| `DS-S03` | A required prop is missing. |
| `DS-S04` | An enum prop has a value outside its allowed set. The message lists the valid values. |
| `DS-S05` | A forbidden nesting pair — two components that must not contain one another. |
| `DS-S06` | An unknown component: not in the catalog and not locally imported. Usually a typo or a component from another platform. |
| `DS-S07` | Component nesting deeper than 4 levels. |

## `DS-D*` — design and density. Warnings.

| Code | Triggered by |
|---|---|
| `DS-D01` | More than 40 component elements on one page. |
| `DS-D02` | More than one `Banner`, more than one `Aside`, or a `Banner` that is not the page's first block. |
| `DS-D03` | Adjacent fenced code blocks in different languages — consider `CodeGroup`. |
| `DS-D04` | An ordered list where every item contains a fenced code block — consider `Steps`. |
| `DS-D05` | Adjacent `Accordion` elements with no enclosing `AccordionGroup`. |
| `DS-D06` | Adjacent callout-family elements — consider grouping. |
| `DS-D07` | An `icon` prop whose value resolves to no known icon. |
| `DS-D08` | A prop from the upstream dialect that Reed's component cannot represent, and therefore drops. |

`DS-D03`, `DS-D04`, `DS-D05` and `DS-D06` are suggestions: the page renders correctly
either way. `DS-D07` and `DS-D08` mean something you wrote is being silently discarded —
treat those as real even though they are warnings.

## `DS-A*` — accessibility. Always errors.

| Code | Triggered by |
|---|---|
| `DS-A01` | An image or `<img>` with no non-empty `alt`. |
| `DS-A02` | An H1 in the page body — the H1 comes from frontmatter `title` — or a skipped heading level, such as `h2` straight to `h4`. |
| `DS-A03` | An `Icon` that is the entire content of a link or button, with no accessible `label`. |

These are errors rather than warnings on purpose: each one produces a page a screen
reader cannot convey, and none has a legitimate exception worth a flag.

## `unsupported-upstream-component`

Not a `DS-*` code, and always an error. The page uses a component that has no equivalent
under the configured `content.dialect`. The fix is either a different component or a
different dialect — see [Content dialect](/docs/authoring/dialect).

## Reading a diagnostic

```
✗ [DS-S03] content file "api/limits.mdx"'s "ParamField" is missing required prop "name" (contract: ParamField)
```

Every diagnostic names the file, the component, and the contract it was judged against.
The contract name matters when dialect mapping is in play: it tells you which set of
rules Reed applied, which is usually the answer when a diagnostic looks wrong.
