---
title: Fix component contract errors (DS-S01 to DS-S05, DS-S07)
description: A known component used the wrong way — bad child, too few children, missing prop, bad value, bad nesting.
---

The component exists, but the way it is used breaks its contract. Find your message below,
then apply the matching fix.

## Symptom

Every message names the file and the component. The part after that tells you which rule
broke. These are real messages from `reed check`, with only the file name changed.

### `DS-S01` — disallowed child

```txt
  ✗ [DS-S01] content file "guides/setup.mdx"'s "CardGroup" has a disallowed child "Note"; permitted children: [Card]
```

### `DS-S02` — too few children

```txt
  ✗ [DS-S02] content file "guides/setup.mdx"'s "Steps" has 1 element child(ren); minimum required is 2
```

### `DS-S03` — missing required prop

```txt
  ✗ [DS-S03] content file "guides/setup.mdx"'s "Accordion" is missing required prop "title" (contract: Accordion)
```

### `DS-S04` — value outside the allowed set

```txt
  ✗ [DS-S04] content file "guides/setup.mdx"'s "Callout" prop "intent" has value "bogus", not one of [info, warning, success, error, note, launch, tip, check]
```

### `DS-S05` — forbidden nesting pair

```txt
  ✗ [DS-S05] content file "guides/setup.mdx" nests "Tip" inside "Note", which is a forbidden pair
```

### `DS-S07` — nested too deep

```txt
  ✗ [DS-S07] content file "guides/setup.mdx"'s "Card" is nested 5 component-elements deep; the maximum is 4
```

One mistake often produces several lines. A `Tabs` nested inside another `Tabs` reports
`DS-S05` for the pair. `Tabs > Tab > Tabs > Tab` is exactly 4 levels, which is allowed;
put a `Card` inside the inner `Tab` and the `Card`, at level 5, reports `DS-S07` as well.
Every element deeper than 4 levels gets its own `DS-S07` line.

## Cause

Every catalog component has a contract: which props it takes, which values an enum prop
accepts, and what it may contain. `reed check` compares each element against its contract
and reports each violation as an error. Errors fail `reed build` too.

The rules you are most likely to hit:

| Component | Contract |
|---|---|
| `Steps` | Only `Step` children, **at least two** |
| `Tabs` | Only `Tab` children, **at least two** |
| `CardGroup` | Only `Card` children, at least one |
| `AccordionGroup` | Only `Accordion` children, at least one |
| `CodeGroup` | Only `CodeBlock` or fenced code blocks, at least one |
| `Frame` | At least one child — a markdown image alone counts; an empty `Frame` does not |
| `Card`, `Step`, `Tab`, `Accordion`, `Expandable` | `title` is required |
| `Callout` | `intent` is required; one of the eight listed values |
| `ParamField` | `name` is required |
| `ResponseField` | `name` and `type` are required |

Nesting has two separate limits. `DS-S05` forbids specific pairs, at any depth:

- any callout (`Note`, `Tip`, `Warning`, `Callout` and the rest) inside another callout;
- a `Banner` inside anything;
- a `Card`, `Accordion`, `Steps`, `CodeGroup`, `Tabs`, `Aside` or `Frame` inside another
  of the same kind;
- `Steps` or `CardGroup` inside a `Card`;
- `Aside` inside `Steps`, `Card` or a callout.

`DS-S07` caps any chain of nested components at four levels.

If `DS-S03` fires on a prop you are sure you wrote, read the contract name at the end of
the message. It tells you which rules Reed applied after dialect mapping. Mintlify's
`<ParamField path="limit">`, for example, has no `name` until `content.dialect` is
`"mintlify"`.

## Fix

**`DS-S01`.** Move the disallowed child out, usually directly after the parent closes,
or wrap its content in a permitted child. A `Note` belongs after the `CardGroup`, not
among the cards.

**`DS-S02`.** A single step is not a procedure. Write it as a paragraph, or add the step
you are missing:

```mdx
<Steps>
  <Step title="Install">Add the dependency.</Step>
  <Step title="Build">Run the build.</Step>
</Steps>
```

A one-tab `Tabs` is the same case: drop the tabs and show the content directly.

**`DS-S03`.** Add the prop named in the message, with a real value. A bare attribute
(`<Step title>`) or a whitespace-only one (`title=" "`) still counts as missing.

**`DS-S04`.** Replace the value with one from the list the message prints. The list is
the complete set Reed accepts for that prop.

**`DS-S05`.** Flatten. Put the second callout after the first instead of inside it. Turn
the inner `Tabs` into headings inside each `Tab`, or split the content across pages.

**`DS-S07`.** Remove a layer. Deep nesting almost always means one wrapper adds nothing —
often an `AccordionGroup` or `CardGroup` inside a `Tab` inside a `Step`. Replace the
outermost wrapper with a heading.

For each component's full props and children, see the reference:
[layout](/docs/reference/components/layout),
[procedural](/docs/reference/components/procedural),
[callouts](/docs/reference/components/callouts),
[API](/docs/reference/components/api),
[file tree](/docs/reference/components/file-tree) and
[the rest](/docs/reference/components/misc).

## Verify

```sh
reed check 2>&1 | grep -E 'DS-S0[1-57]'
```

Expect no output, and a final `check passed.` Then open the page in `reed dev`, since a
flattened structure can read differently from what you had in mind.

## Related

- [Diagnostics](/docs/reference/diagnostics) — every `DS-*` code
- [Components](/docs/authoring/components) — when to reach for a component at all
- [Content dialect](/docs/authoring/dialect)
- [Fix "uses unknown component" (DS-S06)](/docs/troubleshooting/unknown-component)
