Uh oh!
There was an error while loading. Please reload this page.
fix(site): SchemaNode crosses to SchemaRenderer through the bridge — the docs site builds again (#4617) - #4621
Merged
Conversation
…the docs site builds again (#4617) `Build Docs` (`next build`, which type-checks apps/site) has failed on every push to `main` since PR #4608 landed, with 5x TS2322 at the five call sites that hand a `SchemaNode` to `SchemaRenderer`'s `schema` prop. Route all five through `toRenderableSchema`, the adapter #4548-Q2 kept for exactly this crossing: `SchemaNode` deliberately includes `number`/`boolean`, SchemaRenderer's component union deliberately excludes them. Not a prop widening, not a cast. Also close the gate gap that let this reach `main` green: apps/site's type-check script was named `types:check`, so `turbo run type-check` listed it as `<NONEXISTENT>` and never ran it. Renamed to `type-check`; its CHECKED_BY_OWN_BUILD exemption retires with the rename, as that gate's own ratchet requires. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
The latest updates on your projects. Learn more about Vercel for GitHub. |
yinlianghui
marked this pull request as ready for review
August 14, 2026 01:54
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#4617.
mainis red and has been since PR #4608 merged:Build Docsrunspnpm turbo run build --filter='@object-ui/site',next buildtype-checks the site, and the site's fiveSchemaRenderercall sites stopped compiling the momentSchemaNodebecame a union. Every open PR inherits it.Red first — measured against
origin/main, not inherited from the cardCI, run 31740683664 (
mainpush,c1d939f7f= the merge of #4608), jobBuild Docs, stepBuild Site. The immediately precedingmainrun 31736774667 was green:Reproduced locally on a worktree at
origin/main— same five, byte-identical:One correction to the card, kept rather than quietly fixed.#4617's body transcribes the fourth error as
SchemaThumbnail.tsx(145,35). Both the CI log and the local reproduction say 138,35;apps/sitehas not changed sincec1d939f7f(git log c1d939f7f..HEAD -- apps/siteis empty), so 145 is not a stale line number — most likely it came from the filer's own #4615 branch, which edits that file. The other four line numbers match exactly.The fix — the bridge, at five sites
All five values are typed
SchemaNodefrom@object-ui/core, which since #4608 re-exports@object-ui/types' unionBaseSchema | string | number | boolean | null | undefined.SchemaRenderer's prop is narrower on purpose (SchemaRenderer.tsx:226):schema: BaseSchema | string | null | undefined. The sanctioned crossing istoRenderableSchema, which #4608 explicitly preserved for this — quoting its own must-not-change section:It is imported from
@object-ui/react's published surface —packages/react/src/index.ts:10isexport * from './schema-input', so no deep import is involved.app/components/InteractiveDemo.tsx:74toRenderableSchema(example.schema)example.schemaapp/components/InteractiveDemo.tsx:119toRenderableSchema(schema)schemaapp/components/LiveSplitDemo.tsx:286toRenderableSchema(lastValidSchema)lastValidSchemaapp/components/SchemaThumbnail.tsx:138toRenderableSchema(schema)schemaapp/playground/page.tsx:1413toRenderableSchema(schema)schemaPlus one import line per file (four files). No prop widening in
@object-ui/react, noascast, andtoRenderableSchema's implementation is untouched — this PR consumes it.must-not-change: rendered behavior, and the primitive is genuinely reachable
The bridge is identity for every object schema and for
null/undefined; it maps onlynumber/booleanto their text form. That this changes nothing is read from the renderer, not assumed —SchemaRenderer.tsx:483and:489:So
42took the second branch and renderedString(42); bridged, it takes the first branch as"42". Same text node either way. The two branches are the same function composed in the other order.Two of the five sites can really receive a bare primitive today, so this is not a formality:
LiveSplitDemo.tsx:153—setLastValidSchema(parsed as SchemaNode)whereparsed = JSON.parse(text)from the live-editable textarea. Typing42in that box is valid JSON.playground/page.tsx:1244—setSchema(parsed), same shape, from the playground editor.The other three (
InteractiveDemo's two props,SchemaThumbnail's prop) are authored by MDX/gallery callers, where a bare string is the plausible input and passes through untouched. The bridge is total at all five, which is why the ruling's "still the right spelling" holds even where a primitive is unlikely.The gate gap — why this reached
maingreenapps/site's type-check script was namedtypes:check, but the turbo task istype-check. Turbo therefore listed the package in the graph with no command to run:Renamed to
type-check(nothing else in the repo referenced the old name — one grep hit, its own definition). Measured withturbo run type-check --dry=json, counting entries whose command is not the< NONEXISTENT >marker:apps/siteruns...@object-ui/react...@object-ui/typesThose before-counts are worth a second look: 67 and 77 are exactly the "67 / 67 successful" and "77 / 77 successful" that PR #4608's own canary table reported as full green. The canary was honest about what it ran;
apps/sitesimply was not in it, in either direction.scripts/check-type-check-coverage.mjscarried@object-ui/siteinCHECKED_BY_OWN_BUILD. That gate's own ratchet (line 532) requires the entry to die once the package gains atype-checkscript, so it is deleted and the table is now empty, with a comment recording why it should stay that way:The retired entry's own caveat had predicted this failure in the abstract — "a PR that only touches a workspace package in
transpilePackagestherefore does not re-check the site until it lands" — and called it a cost/coverage call. #4608 is that PR, and the answer turned out to be ~5 hours of redmain. The exemption was accurate about what checked the site and silent about when; "when" was the half that mattered.verifyNoIgnoreBuildErrorsretires with it rather than being orphaned: it protected a coverage claim that rested onnext build, and coverage no longer rests there.The remaining "1 not compiled" is
@object-ui/example-hello-world, unchanged. (#4617's second half describesapps/siteas that "1 not compiled" package; it was in fact the "1 via their own build". No consequence for the fix.)Green
Build Docs' exact step, run verbatim on this branch:
And the newly-aligned turbo task, which now actually executes rather than being skipped:
cache miss, executingis the line that matters: before this PR that package contributed no task to run at all.Verification
check-control-bytes.mjscheck-phantom-dependencies.mjscheck-changeset-presence.mjssrc/, 0 changesets owedcheck-changeset-no-major.mjscheck-changeset-fixed.mjscheck-type-check-coverage.mjscheck-lint-coverage.mjscheck-doc-links.mjsvitest run scripts/origin/mainin a compare worktree; net zeroControl-byte self-scan (
grep -naPover the widened class, not just NUL) clean on all six touched files.CI on this branch — converged
All 18 check runs completed; 16
success, 2skippedby their own conditions (dependabot,Test (coverage)). The headline:mainpush since #4608apps/sitefor the first timeChangesets
None, and the gate agrees rather than being overridden:
apps/siteis"private": trueand publishes nothing; the script rename and the gate-table edit are tooling. Never major.No
skip-changesetlabel is applied, deliberately — that label does not exist in this repo.changeset-presence.ymlrunsnode scripts/check-changeset-presence.mjswith no label escape hatch, andscripts/__tests__/ci-cd-pipeline-doc.test.ts:184records that a "changeset gate skippable with askip-changesetlabel" was one of the five phantom workflows objectui#3724 deleted — "neither the workflow nor the label was ever real". Applying it here would be re-creating that phantom.Scope
packages/reactuntouched — prop types andtoRenderableSchema's implementation alike.packages/plugin-dashboard/src/**untouched (#4614). The five sites are fixed as they exist onorigin/main; #4615's branch was not pulled.content/docs/releases/**untouched. Nogit stashat any point.Generated by Claude Code