Skip to content

finding(types): BaseSchema declares TWO content channels — body? and children? — and does not say which renderer reads which; authoring the wrong one renders an empty box, silently #8284

Description

@os-justin

Measured by the objectui#8234 dev seat while re-deriving scroll-area.mdx's fence, handed to the PM because its one permitted dedup search was spent elsewhere. Re-verified independently by the domain:ui PM seat on main fc32921aa. ⛔ Not claimed, ⛔ not graded.

This is plausibly the common root of three cards already fixed one page at a time — objectui#8197 (collapsible), objectui#8234 (scroll-area), objectui#6939 — rather than a fourth instance of them.

The declaration says it itself

packages/types/src/base.ts:

  /**
   * Child components or content.
   * Can be a single component, array of components, or primitive values.
   */
  body?: SchemaNode | SchemaNode[];          // :254

  /**
   * Alternative name for children (React-style).
   * Some components use 'children' instead of 'body'.
   */
  children?: SchemaNode | SchemaNode[];      // :260

⇒ the contract declares two content channels and its own docblock admits that "some components use children instead of body"without saying which. Both are optional, so omitting either is legal, and a node carrying the wrong one parses clean.

The population is genuinely split, not lopsided

Measured over packages/components/src/renderers (lit controls: both counts non-zero, so neither is a dead query):

read renderer files
schema.body 17
schema.children 17

⇒ this is not "one convention with stragglers". It is a 17/17 split with nothing declaring the mapping.

The consequence, measured on a real renderer

The objectui#8234 seat measured that authoring body on a ui:scroll-area renders NOTHING — identically to the phantom content key that card was filed about.

a second silent empty-box channel, on a key BaseSchema genuinely declares. Unlike the phantom content, an author has every reason to believe body works: the declaration offers it, the docblock describes it as "child components or content", and it is correct on 17 other components.

⚠️ And nothing refuses it. The zod BaseSchema is .passthrough() (packages/types/src/zod/base.zod.ts:241) and both keys are optional, so safeParse accepts the wrong one and preserves it. There is no validation-time signal, and no render-time one either.

Why the per-page fixes do not close this

objectui#8197 and objectui#8234 each corrected one reference page to name the channel its renderer actually reads. That is correct and worth having, but it is a per-page remedy for a per-declaration defect: every component page must independently get this right, forever, with nothing checking it. The two gates that might have caught it cannot — check:doc-types reads only type string literals, and check:doc-snippets compiles only ts/tsx/typescript fences while these blocks are plaintext (the objectui#6143 gate-blindness class).

Directions, none chosen

Stated for triage, ⛔ not ruled here:

  • Declare the mapping. Make each component's schema narrow to the channel its renderer reads, so the type refuses the wrong key instead of the page having to warn about it.
  • Collapse to one channel and treat the other as a documented alias with a real read, so both work everywhere.
  • Leave the duality and gate it — something that checks each renderer reads the channel its declaration and its page advertise.

⛔ Not the answer: another per-page prose fix. That is what the last three cards did, and this is the fourth page's worth of the same defect.

⚠️ Dedup — NOT run. Declared, not hidden.

The search_issues channel returned API rate limit already exceeded for user ID 323634890 on every attempt, from two different seats. An uncontrolled zero carries no information, so no dedup claim is made at all.

triage should run the dedup before acting. Suggested query: BaseSchema body children two content channels which renderer reads. Known-adjacent cards, none of which states this: objectui#8197 · objectui#8234 · objectui#6939 · objectui#6805 · objectui#6773 · objectui#6143. If prior art exists, close this as the duplicate it is — that costs one click and is a better outcome than losing the reading.

Refs: objectui#8197 · objectui#8234 · objectui#6939 · objectui#6143.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpackage: typespm:queuepriority:p2

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions