# Refusals (/docs/reference/refusals)

> Every refusal PageSchema returns, by path, with its bound and the fix.

A refusal is the parse error naming a field over its bound, and the fix is shorter content. A path's anchor is the block's `type`, then the path after `block` with list indexes dropped: `sections.1.block.title` on a `hero` is `#hero.title`. A shell path is `#shell.<field>`, and a field of the Page is `#page.<field>`.

From `@mdxui/site@7.0.0-alpha.0`: 285 anchors. `pnpm check` trips 262 of the bounds on a built record and checks each message below against the one returned.

| Refusal | Message, as `safeParse` returns it | Fix |
| --- | --- | --- |
| A string past its bound | `Too big: expected string to have <=160 characters` | Shorten the content |
| A list past its count | `Too big: expected array to have <=6 items` | Drop items |
| A list short of its count | `Too small: expected array to have >=1 items` | Add items |
| A list off its one count | `Too big: expected array to have exactly 3 items` | Hold the count exactly |
| A number past its range | `Too big: expected number to be <=640` | Use a value inside the range |
| An empty string | `Too small: expected string to have >=1 characters` | Write the value, or leave the field out where it is optional |

## page

| Anchor | Bound |
| --- | --- |
| `page.title` | 64 characters |
| `page.description` | 320 characters |
| `page.meta.canonical` | 160 characters |
| `page.meta.icon` | 160 characters |
| `page.meta.iconFallback` | 160 characters |
| `page.meta.appleTouchIcon` | 160 characters |
| `page.meta.image.url` | 160 characters |
| `page.meta.image.width` | 200 to 2400 |
| `page.meta.image.height` | 200 to 2400 |
| `page.sections` | 3 to 20 items |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `page.theme` | `Invalid option: expected one of "certificate"\|"vaultline"\|"quaypoint"\|"callboard"\|"directory"` | Name a bundled Theme, or render under your own with `render`, as in [Write a Theme](https://next.mdxui.dev/docs/themes/write-a-theme) |

## shell

| Anchor | Bound |
| --- | --- |
| `shell.id` | `^[a-z][a-z0-9-]{0,23}$`: a lowercase letter, then at most 23 letters, digits and hyphens |

## nav

| Anchor | Bound |
| --- | --- |
| `nav.brand.href` | 160 characters |
| `nav.brand.text` | 16 characters |
| `nav.brand.suffix` | 8 characters |
| `nav.links` | at most 6 items |
| `nav.cta.href` | 160 characters |
| `nav.cta.label` | 24 characters |
| `nav.search.action` | 160 characters |
| `nav.search.placeholder` | 40 characters |
| `nav.search.query` | 120 characters |
| `nav.search.clear` | 160 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `nav.brand` | `a brand needs a wordmark or a mark` | Give the brand a wordmark (`text`) or a `mark` |
| `nav` | `a bar's row holds 96 units (its link labels, 3 a link, and twice the wider of the brand and the button); shorten a label or drop a link` | Shorten a link label or drop a link |

## footer

| Anchor | Bound |
| --- | --- |
| `footer.brand.href` | 160 characters |
| `footer.brand.text` | 16 characters |
| `footer.brand.suffix` | 8 characters |
| `footer.blurb` | 160 characters |
| `footer.columns` | at most 4 items |
| `footer.columns.title` | 16 characters |
| `footer.columns.label` | 40 characters |
| `footer.columns.links` | 1 to 12 items |
| `footer.cta.href` | 160 characters |
| `footer.cta.label` | 24 characters |
| `footer.social` | at most 6 items |
| `footer.social.href` | 160 characters |
| `footer.form.action` | 160 characters |
| `footer.form.label` | 24 characters |
| `footer.form.placeholder` | 32 characters |
| `footer.form.submit` | 16 characters |
| `footer.note` | exactly 2 items |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `footer.brand` | `a brand needs a wordmark or a mark` | Give the brand a wordmark (`text`) or a `mark` |
| `footer` | `a footer in columns holds two or three of them` | Use two or three columns |
| `footer` | `a footer in columns has a "For agents" column` | Title one column "For agents" |

## hero

| Anchor | Bound |
| --- | --- |
| `hero.kicker.text` | 40 characters |
| `hero.title` | 64 characters |
| `hero.lede` | 260 characters |
| `hero.actions` | at most 2 items |
| `hero.actions.href` | 160 characters |
| `hero.actions.label` | 24 characters |
| `hero.command.command` | 40 characters |
| `hero.command.note` | 48 characters |
| `hero.fine` | at most 4 items |
| `hero.specimen.blocks` | 1 to 3 items |

## statement

| Anchor | Bound |
| --- | --- |
| `statement.text` | 140 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `statement.text` | `` a statement is plain words and one `*accent phrase*`: no code, link, strong or mark `` | Write plain words and at most one `*accent phrase*` |

## page-head

| Anchor | Bound |
| --- | --- |
| `page-head.title` | 64 characters |
| `page-head.lede` | 200 characters |

## stats

| Anchor | Bound |
| --- | --- |
| `stats.head.eyebrow` | 28 characters |
| `stats.head.title` | 72 characters |
| `stats.head.lede` | 300 characters |
| `stats.head.tag` | 8 characters |
| `stats.items` | 3 to 4 items |
| `stats.items.value` | 6 characters |
| `stats.items.label` | 72 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `stats.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## facts

| Anchor | Bound |
| --- | --- |
| `facts.title` | 48 characters |
| `facts.items` | 1 to 16 items |
| `facts.items.label` | 24 characters |
| `facts.items.value` | 80 characters |
| `facts.items.href` | 160 characters |

## feature-grid

| Anchor | Bound |
| --- | --- |
| `feature-grid.head.eyebrow` | 28 characters |
| `feature-grid.head.title` | 72 characters |
| `feature-grid.head.lede` | 300 characters |
| `feature-grid.head.tag` | 8 characters |
| `feature-grid.aside.command` | 12 characters |
| `feature-grid.aside.note` | 40 characters |
| `feature-grid.items` | 2 to 8 items |
| `feature-grid.items.label` | 24 characters |
| `feature-grid.items.index` | 2 characters |
| `feature-grid.items.title` | 40 characters |
| `feature-grid.items.text` | 200 characters |
| `feature-grid.items.href` | 160 characters |
| `feature-grid.items.linkLabel` | 24 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `feature-grid.head` | `a head needs a title or a lede` | Give the head a title or a lede |
| `feature-grid.items` | `a feature grid holds 2, 3, 4, 6, 8 cells: a count that fills its rows at every width` | Use 2, 3, 4, 6 or 8 items |
| `feature-grid.items` | `an item needs a title or a text` | Give the item a title or a text |

## feature-split

| Anchor | Bound |
| --- | --- |
| `feature-split.head.eyebrow` | 28 characters |
| `feature-split.head.title` | 72 characters |
| `feature-split.head.lede` | 300 characters |
| `feature-split.head.tag` | 8 characters |
| `feature-split.bases` | exactly 2 items |
| `feature-split.items` | exactly 3 items |
| `feature-split.items.index` | 2 characters |
| `feature-split.items.title` | 28 characters |
| `feature-split.items.text` | 96 characters |
| `feature-split.items.bullets` | at most 4 items |
| `feature-split.specimen.blocks` | 1 to 3 items |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `feature-split.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## bento

| Anchor | Bound |
| --- | --- |
| `bento.head.eyebrow` | 28 characters |
| `bento.head.title` | 72 characters |
| `bento.head.lede` | 300 characters |
| `bento.head.tag` | 8 characters |
| `bento.panels` | 2 to 4 items |
| `bento.panels.title` | 48 characters |
| `bento.panels.text` | 120 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `bento.head` | `a head needs a title or a lede` | Give the head a title or a lede |
| `bento.panels` | `a bento panel holds one specimen: terminal, agent-prompt, api-call` | Hold one `terminal`, `agent-prompt`, `api-call` in the tile |

## compare

| Anchor | Bound |
| --- | --- |
| `compare.head.eyebrow` | 28 characters |
| `compare.head.title` | 72 characters |
| `compare.head.lede` | 300 characters |
| `compare.head.tag` | 8 characters |
| `compare.cons.label` | 24 characters |
| `compare.cons.items` | 1 to 8 items |
| `compare.pros.label` | 24 characters |
| `compare.pros.items` | 1 to 8 items |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `compare.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## steps

| Anchor | Bound |
| --- | --- |
| `steps.head.eyebrow` | 28 characters |
| `steps.head.title` | 72 characters |
| `steps.head.lede` | 300 characters |
| `steps.head.tag` | 8 characters |
| `steps.more` | at most 2 items |
| `steps.steps` | 3 to 5 items |
| `steps.specimen.blocks` | 1 to 3 items |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `steps.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## text-stack

| Anchor | Bound |
| --- | --- |
| `text-stack.head.eyebrow` | 28 characters |
| `text-stack.head.title` | 72 characters |
| `text-stack.head.lede` | 300 characters |
| `text-stack.head.tag` | 8 characters |
| `text-stack.items` | 3 to 6 items |
| `text-stack.items.title` | 28 characters |
| `text-stack.items.text` | 160 characters |
| `text-stack.items.href` | 160 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `text-stack.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## terminal

| Anchor | Bound |
| --- | --- |
| `terminal.title` | 48 characters |
| `terminal.lines` | 1 to 32 items |
| `terminal.tabs` | 1 to 4 items |
| `terminal.tabs.label` | 6 characters |
| `terminal.tabs.lines` | 1 to 24 items |
| `terminal.tabs.lines.cmd` | 64 characters |
| `terminal.tabs.lines.row` | exactly 2 items |
| `terminal.tabs.lines.out` | 64 characters |
| `terminal.tabs.lines.text` | 128 characters |

## command-row

| Anchor | Bound |
| --- | --- |
| `command-row.command` | 40 characters |
| `command-row.note` | 48 characters |

## api-call

| Anchor | Bound |
| --- | --- |
| `api-call.path` | 72 characters |
| `api-call.note` | 32 characters |
| `api-call.examples` | 1 to 4 items |
| `api-call.examples.label` | 28 characters |
| `api-call.examples.request` | 1008 characters |
| `api-call.examples.status` | 28 characters |
| `api-call.examples.response` | 1728 characters |
| `api-call.examples.events` | 1 to 10 items |
| `api-call.examples.events.at` | 12 characters |
| `api-call.examples.events.name` | 40 characters |
| `api-call.examples.events.ref` | 16 characters |
| `api-call.examples.events.text` | 80 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `api-call.examples` | `an example answers with a response or with events, one of them` | Answer with a `response` or with `events`, one of them |

## endpoints

| Anchor | Bound |
| --- | --- |
| `endpoints.head.eyebrow` | 28 characters |
| `endpoints.head.title` | 72 characters |
| `endpoints.head.lede` | 300 characters |
| `endpoints.head.tag` | 8 characters |
| `endpoints.rows` | 3 to 16 items |
| `endpoints.rows.path` | 64 characters |
| `endpoints.rows.text` | 96 characters |
| `endpoints.rows.href` | 160 characters |
| `endpoints.note` | 160 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `endpoints.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## agent-prompt

| Anchor | Bound |
| --- | --- |
| `agent-prompt.label` | 24 characters |
| `agent-prompt.lines` | 1 to 6 items |

## pricing

| Anchor | Bound |
| --- | --- |
| `pricing.head.eyebrow` | 28 characters |
| `pricing.head.title` | 72 characters |
| `pricing.head.lede` | 300 characters |
| `pricing.head.tag` | 8 characters |
| `pricing.tiers` | 1 to 4 items |
| `pricing.tiers.name` | 16 characters |
| `pricing.tiers.price` | 16 characters |
| `pricing.tiers.note` | 24 characters |
| `pricing.tiers.desc` | 80 characters |
| `pricing.tiers.features` | 1 to 10 items |
| `pricing.tiers.cta` | 40 characters |
| `pricing.tiers.href` | 160 characters |
| `pricing.featuredBadge` | 16 characters |
| `pricing.note` | 120 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `pricing.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## plan-table

| Anchor | Bound |
| --- | --- |
| `plan-table.title` | 48 characters |
| `plan-table.columns` | 1 to 6 items |
| `plan-table.rows` | 1 to 8 items |
| `plan-table.rows.name` | 24 characters |
| `plan-table.rows.cells` | 1 to 6 items |
| `plan-table.rows.note` | 40 characters |
| `plan-table.foot` | 160 characters |

## faq

| Anchor | Bound |
| --- | --- |
| `faq.head.eyebrow` | 28 characters |
| `faq.head.title` | 72 characters |
| `faq.head.lede` | 300 characters |
| `faq.head.tag` | 8 characters |
| `faq.items` | 1 to 10 items |
| `faq.items.q` | 64 characters |
| `faq.items.a` | 420 characters |
| `faq.groups` | 1 to 4 items |
| `faq.groups.title` | 24 characters |
| `faq.groups.items` | 1 to 6 items |
| `faq.groups.items.q` | 64 characters |
| `faq.groups.items.a` | 420 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `faq.head` | `a head needs a title or a lede` | Give the head a title or a lede |
| `faq` | `items or groups, not both` | Keep `items` or `groups`, never both |

## closing

| Anchor | Bound |
| --- | --- |
| `closing.head.eyebrow` | 28 characters |
| `closing.head.title` | 72 characters |
| `closing.head.lede` | 300 characters |
| `closing.head.tag` | 8 characters |
| `closing.specimen.blocks` | 1 to 3 items |
| `closing.fine` | at most 4 items |
| `closing.stats` | at most 4 items |
| `closing.stats.value` | 6 characters |
| `closing.stats.label` | 24 characters |
| `closing.actions` | at most 2 items |
| `closing.actions.href` | 160 characters |
| `closing.actions.label` | 24 characters |
| `closing.command` | 40 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `closing.head` | `a head needs a title or a lede` | Give the head a title or a lede |
| `closing` | `a closing ends on its buttons or on one command, never both (review 2026-09-14)` | Keep the `actions` or the `command`, never both |

## cta-form

| Anchor | Bound |
| --- | --- |
| `cta-form.head.eyebrow` | 28 characters |
| `cta-form.head.title` | 72 characters |
| `cta-form.head.lede` | 300 characters |
| `cta-form.head.tag` | 8 characters |
| `cta-form.action` | 160 characters |
| `cta-form.fields` | 1 to 8 items |
| `cta-form.fields.label` | 16 characters |
| `cta-form.fields.placeholder` | 32 characters |
| `cta-form.fields.options` | at most 12 items |
| `cta-form.submit` | 24 characters |
| `cta-form.note` | 80 characters |

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `cta-form.head` | `a head needs a title or a lede` | Give the head a title or a lede |

## article

| Anchor | Bound |
| --- | --- |
| `article.head.back.href` | 160 characters |
| `article.head.back.label` | 16 characters |
| `article.head.tag` | 20 characters |
| `article.head.dateline.read.minutes` | 1 to 180 |
| `article.head.dateline.read.unit` | 12 characters |
| `article.head.title` | 80 characters |
| `article.head.dek` | 360 characters |
| `article.share.url` | 160 characters |
| `article.share.title` | 80 characters |
| `article.share.label` | 16 characters |
| `article.share.on` | 1 to 5 items |
| `article.body` | 12000 characters |

## post-list

| Anchor | Bound |
| --- | --- |
| `post-list.head.eyebrow` | 28 characters |
| `post-list.head.title` | 64 characters |
| `post-list.head.lede` | 200 characters |
| `post-list.read` | 16 characters |
| `post-list.posts` | 1 to 24 items |
| `post-list.posts.href` | 160 characters |
| `post-list.posts.tag` | 20 characters |
| `post-list.posts.dateline.read.minutes` | 1 to 180 |
| `post-list.posts.dateline.read.unit` | 12 characters |
| `post-list.posts.title` | 80 characters |
| `post-list.posts.dek` | 360 characters |

## product-head

| Anchor | Bound |
| --- | --- |
| `product-head.name` | 32 characters |
| `product-head.summary` | 120 characters |
| `product-head.chips` | at most 9 items |
| `product-head.chips.label` | 24 characters |
| `product-head.chips.href` | 160 characters |
| `product-head.actions` | 1 to 2 items |
| `product-head.actions.href` | 160 characters |
| `product-head.actions.label` | 24 characters |

## product-list

| Anchor | Bound |
| --- | --- |
| `product-list.title` | 48 characters |
| `product-list.note` | 24 characters |
| `product-list.rail.groups` | 1 to 4 items |
| `product-list.rail.groups.label` | 20 characters |
| `product-list.rail.groups.links` | 1 to 12 items |
| `product-list.rail.groups.links.href` | 160 characters |
| `product-list.rail.groups.links.label` | 24 characters |
| `product-list.rail.groups.links.count` | 0 to 1000000 |
| `product-list.sort` | at most 4 items |
| `product-list.sort.href` | 160 characters |
| `product-list.sort.label` | 16 characters |
| `product-list.views` | at most 2 items |
| `product-list.views.href` | 160 characters |
| `product-list.views.label` | 16 characters |
| `product-list.rows` | at most 50 items |
| `product-list.rows.href` | 160 characters |
| `product-list.rows.name` | 32 characters |
| `product-list.rows.summary` | 120 characters |
| `product-list.rows.tag` | 24 characters |
| `product-list.rows.note` | 32 characters |
| `product-list.pager.prev` | 160 characters |
| `product-list.pager.next` | 160 characters |
| `product-list.pager.page` | 1 to 10000 |
| `product-list.pager.pages` | 1 to 10000 |
| `product-list.empty` | 80 characters |

## compileTheme

| Anchor | Rule, as `safeParse` returns it | Fix |
| --- | --- | --- |
| `compile-theme` | `theme "fieldnote" is missing core roles: panel, ink, …` | Set every [core role](https://next.mdxui.dev/docs/themes/contract) in `light` or `invariant` |

