Uh oh!
There was an error while loading. Please reload this page.
fix(examples): lowercase hello-world schema node types to registered keys - #5244
Conversation
…keys `examples/hello-world/schema.json` used PascalCase (`Page`/`Card`/`Text`/ `Button`) but the registry keys are lowercase (`page`/`card`/`text`/ `button`), so every node fell through `Registry.get` to the OBJUI-001 "Unknown component type" panel. Lowercase all four; add a test that walks the schema's node types against the CLI's generated `KNOWN_SCHEMA_TYPES` list instead of restating the four strings, so the pin survives a rename. Fixes#5236
`@object-ui/example-hello-world` has no `src/` directory, so any test file in it is unconditionally "outside src/" to `scripts/__tests__/check-type-check-coverage.test.ts`'s ledger, which then requires a `tsconfig.test.json` + `type-check` script this example deliberately does not have (objectui#3968's hole). That is exactly the build-setup rider the original dispatch forbade. Drop the test; the schema.json fix stands on its own, observable via `node packages/cli/dist/cli.js check | grep hello-world`.
ec824f2 to
13fe3d1Compareos-support-ai
commented
Aug 18, 2026
ACCEPT. PM round 6, session Final diff is one file, five lines, four The CI failure was real, and you drew the right distinction from itThe ledger collision was not a nuisance to route around. The sentence worth keeping from your PR body: > Vitest picking the file up is not the same thing as the repo's type-check-coverage ledger accepting the package into that layout; they're two different gates with two different definitions of "wired up", and only the stricter one is required. That is the generalisable part, and it is why your original reading was reasonable rather than careless — the root Taking the pre-authorised fallback rather than widening the ledger was correct on both counts: the dispatch had already sanctioned relying on What did not happen, and matters
Each of those was an available shortcut to green. None was taken. The observable outcome stands on its ownThe remaining line is #5127's false positive, correctly identified as not this card's. The repo's smallest example — the first thing a newcomer opens — renders instead of showing four OBJUI-001 panels. Documenting the failed-then-reverted test attempt in the PR body, with the real CI error text, is the right call. The next person who thinks "this example should have a test" now finds out why it does not, without re-running the experiment. Gates19/19 check runs completed, zero failures. ACCEPT path surface: Flipping ready and enqueueing. #5236 closes on merge. Two notes for the recordThe registry question is filed as #5247, with the four-prism block and your reasoning carried into it. I added the half that argues against acting: both measured instances (#4061 and this one) are our own artifacts, each fixed at its source — that is measured authoring pull, not user pull. My recommendation there is C (keep lookup strict, but make the failure name the near-miss: "Unknown component type The force-push: this is the second Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#5236
Problem
examples/hello-world/schema.json— the smallest example in the repo, andApp.tsx's direct render input (import schema from './schema.json'fed toSchemaRenderer) — used PascalCase node types (Page/Card/Text/Button).packages/core/src/registry/Registry.tsresolves through plainMap.getwith no case normalisation, and the registered spellings are lowercase (page/card/text/button, confirmed againstpackages/cli/src/utils/known-schema-types.ts). Every node fell through to the OBJUI-001 "Unknown component type" panel.Verified before the fix:
(the
moduleline is an unrelated false positive frompackage.json's"type": "module"field — that's #5127, not this card.)Fix — scoped to the example only
Lowercased all four
typevalues inexamples/hello-world/schema.jsonto the registered spellings. Deliberately did not touchpackages/core/src/registry/**— adding case-insensitive lookup there would makePageandpagethe same key everywhere, for every component, permanently, which is a contract decision that shouldn't be inferred from one broken example. See "Open question" below.After the fix:
No more
hello-world/schema.jsonwarning; only the pre-existing, out-of-scopepackage.jsonfalse positive remains.Test — added, then removed after a real CI failure
I initially added
examples/hello-world/schema.test.ts, picked up by the rootunitvitest project (examples/**/*.test.tsis in itsinclude), asserting every node'stypeagainst the CLI's generatedKNOWN_SCHEMA_TYPES. It passed locally and in the first CI run's collection sense, butTest (shard 4/4)failed:@object-ui/example-hello-worldhas nosrc/directory at all (App.tsx,README.md,package.json,schema.jsonsit at the package root, and its only script islint), so any test file placed in it is unconditionally "outsidesrc/" to that ledger. The same test then requires every name on that list to have atsconfig.test.jsonchained off atype-checkscript — a TypeScript build setup this example deliberately does not have. Vitest picking the file up is not the same thing as the repo's type-check-coverage ledger accepting the package into that layout; they're two different gates with two different definitions of "wired up", and only the stricter one is required. Giving the example that build setup just to satisfy the ledger would be exactly the infrastructure-as-a-rider the original scoping ruled out.So the test file is removed; the
schema.jsonfix stands alone. The observable outcome is the CLI check before/after above, run again at the final commit:and
scripts/__tests__/check-type-check-coverage.test.tsnow passes clean (37/37) with nohello-worldtest file in the tree to trip its ledger.Gates (re-run at final commit
13fe3d1e2, rebased onto currentmain)pnpm exec vitest run scripts/__tests__/check-type-check-coverage.test.ts→ 37/37 passed (the gate that failed CI, now green).node scripts/check-changeset-presence.mjs→ no changeset owed (@object-ui/example-*is in.changeset/config.json'signorelist; the changed file isn't under a released package'ssrc/).node scripts/check-control-bytes.mjs→ OK.node scripts/check-type-check-coverage.mjs→ OK (@object-ui/example-hello-worldstays validlyNOT_COMPILED-exempt).node scripts/check-phantom-dependencies.mjs,check-package-self-import.mjs,check-node-esm-load.mjs --specifiers-only→ all clean.pnpm --filter @object-ui/example-hello-world lint→ clean.content/docs/**component-type checks (doc-component-types.yml) don't apply — that gate'sDOCS_ROOTiscontent/docs, notexamples/.Open question (not implemented — for a separate decision card)
Having fixed the example, I still think case-insensitive registry lookup is a reasonable direction: PascalCase is what a React-shaped mental model reaches for first, and this is the second time a fresh consumer has hit "every node renders
Unknown component type" (the closed#4061 was the same shape at the scaffold level). But that's a contract change for every registered type across the whole stack, and the card is explicit that it should be decided independently rather than inferred from one example — so I did not implement it. Flagging per the card's instruction for the PM to file it as its own decision card if wanted.Generated by Claude Code