Found in passing while implementing objectui#6250 (the toast/sonner demo shapes). Same defect class — a docs-facing key that is declared nowhere and executed nowhere — but a different shape, so it was not folded into that PR: #6250's charter covers "an action object hung off a handler key", and this is a plain scalar key on a different component. Filing rather than widening.
Measured on 7975f2d85
provider is authored by three catalog fixtures and taught by the page prose:
examples/schema-catalog/src/schemas/components-feedback-toaster/default-provider.json — {"type":"toaster","provider":"default"}examples/schema-catalog/src/schemas/components-feedback-toaster/sonner-provider.json — {"type":"toaster","provider":"sonner"}examples/schema-catalog/src/schemas/components-feedback-toaster/custom-position-limit.json — nested, {"type":"toaster","provider":"sonner","position":"top-right","limit":3}content/docs/components/feedback/toaster.mdx — "ObjectUI supports two toast providers", a <DemoGrid> showing the two of them side by side, and a schema block documenting provider?: 'default' | 'sonner' // Toast provider (default: 'default')
Declared nowhere.ToasterSchema (packages/types/src/feedback.ts:156, mirror at packages/types/src/zod/feedback.zod.ts:82) declares type, position and limit. No provider. BaseSchema is .passthrough() and carries [key: string]: any, so both zod and tsc accept the key silently — .success is not a usable probe here, the same way it was not for direction on radio-group (objectui#6157).
Read nowhere.packages/components/src/renderers/feedback/toaster.tsx reads exactly two keys:
constposition=schema?.position ? TOASTER_POSITIONS[schema.position] : undefined;// :43constlimit=typeofschema?.limit==='number'&&schema.limit>0 ? schema.limit : undefined;// :44
and then mounts sonner's <Toaster /> unconditionally. Grepped packages/**/src for a provider read on a component schema: every hit belongs to the data-source vocabulary (ViewData.provider in core/src/data-scope/ViewDataProvider.ts, adapters/resolveDataSource.ts, react/src/hooks/useViewData.ts) — none is this key. Positive control for that grep: the same shape finds schema.position, which the file above genuinely reads.
Consequence. The two "provider" demos render byte-identically, because both mount the same sonner toaster. The page teaches a choice that does not exist, and the docs gallery shows two tiles that differ only in the JSON printed beside them.
Why it is not obviously a fixture-only fix
The page makes a capability claim ("ObjectUI supports two toast providers"), and packages/components/src/ui/toast.tsx does ship a second, Radix-based toast primitive (ToastProvider and friends) that nothing routes a schema to. So the two resolutions differ in kind:
- the fixtures and page are wrong — drop
provider, and the page documents one toaster; or - the renderer is wrong —
provider: 'default' was meant to mount the Radix primitive, and ToasterSchema needs to declare the key.
That is a contract question rather than a typo, which is why this is a finding and not a fix. Unassigned; no grading — triage's call.
Refs: objectui#6250 · objectui#5250 · objectui#6157 · objectui#6161.
Filed by the objectui#6250 execution seat, session session_011SfZeFWrhGLHmfq61xbz4q.
Generated by Claude Code
Found in passing while implementing objectui#6250 (the toast/sonner demo shapes). Same defect class — a docs-facing key that is declared nowhere and executed nowhere — but a different shape, so it was not folded into that PR: #6250's charter covers "an action object hung off a handler key", and this is a plain scalar key on a different component. Filing rather than widening.
Measured on
7975f2d85provideris authored by three catalog fixtures and taught by the page prose:examples/schema-catalog/src/schemas/components-feedback-toaster/default-provider.json—{"type":"toaster","provider":"default"}examples/schema-catalog/src/schemas/components-feedback-toaster/sonner-provider.json—{"type":"toaster","provider":"sonner"}examples/schema-catalog/src/schemas/components-feedback-toaster/custom-position-limit.json— nested,{"type":"toaster","provider":"sonner","position":"top-right","limit":3}content/docs/components/feedback/toaster.mdx— "ObjectUI supports two toast providers", a<DemoGrid>showing the two of them side by side, and a schema block documentingprovider?: 'default' | 'sonner' // Toast provider (default: 'default')Declared nowhere.
ToasterSchema(packages/types/src/feedback.ts:156, mirror atpackages/types/src/zod/feedback.zod.ts:82) declarestype,positionandlimit. Noprovider.BaseSchemais.passthrough()and carries[key: string]: any, so both zod and tsc accept the key silently —.successis not a usable probe here, the same way it was not fordirectiononradio-group(objectui#6157).Read nowhere.
packages/components/src/renderers/feedback/toaster.tsxreads exactly two keys:and then mounts sonner's
<Toaster />unconditionally. Greppedpackages/**/srcfor aproviderread on a component schema: every hit belongs to the data-source vocabulary (ViewData.providerincore/src/data-scope/ViewDataProvider.ts,adapters/resolveDataSource.ts,react/src/hooks/useViewData.ts) — none is this key. Positive control for that grep: the same shape findsschema.position, which the file above genuinely reads.Consequence. The two "provider" demos render byte-identically, because both mount the same sonner toaster. The page teaches a choice that does not exist, and the docs gallery shows two tiles that differ only in the JSON printed beside them.
Why it is not obviously a fixture-only fix
The page makes a capability claim ("ObjectUI supports two toast providers"), and
packages/components/src/ui/toast.tsxdoes ship a second, Radix-based toast primitive (ToastProviderand friends) that nothing routes a schema to. So the two resolutions differ in kind:provider, and the page documents one toaster; orprovider: 'default'was meant to mount the Radix primitive, andToasterSchemaneeds to declare the key.That is a contract question rather than a typo, which is why this is a finding and not a fix. Unassigned; no grading — triage's call.
Refs: objectui#6250 · objectui#5250 · objectui#6157 · objectui#6161.
Filed by the objectui#6250 execution seat, session
session_011SfZeFWrhGLHmfq61xbz4q.Generated by Claude Code