Uh oh!
There was an error while loading. Please reload this page.
test(console): resolve the binding-reach probe's reading-'map' error cards as a fixture defect, and guard render on both branches - #5943
Merged
Conversation
…ample and guard render on both branches
The two blocks that painted a `reading 'map'` error card under this probe were
a FIXTURE defect, not a product one. Resolved by measurement rather than by
"the crash went away when I changed the sample", which is true either way:
- Bisected to the `sections` input. `ObjectForm.tsx:1166` reads
`section.fields.map(...)` off each entry; the generic `array` sample is the
bare string `['name']`, so `section.fields` is `undefined`.
- Read the spec shape for that input, which is the step that discriminates:
`FormViewSchema.sections` REJECTS `['name']` at parse ("expected object,
received string") and requires `fields` on every entry. `ObjectFormSection`
in this repo agrees — `fields` is required. So no author could publish the
configuration the fixture was handing the form family.
`object-master-detail-form` no longer crashes on today's main, but only by
accident: it declares `formType` as a bare `string`, so the generic sample was
`'x'`, which skips the gate at `ObjectForm.tsx:1134`
(`!schema.formType || schema.formType === 'simple'`) that guards the crashing
loop. Forcing `formType: 'simple'` reproduces the identical crash, so that
sample is corrected too — a value outside a prop's vocabulary routes around the
block instead of exercising it.
Both are recorded as the fifth and sixth instances of the lesson this file
counts (a plausible value for every input is not a plausible configuration),
with the spec quotes inline so the next reader can check rather than trust.
With the blocks green, the crash guard moves ahead of the branch split as
`assertRendered`, matching the sibling probe `record-block-record-reach.test.tsx`
and covering all 14 candidates: a crash is not a binding verdict on either
branch.…asing nothing Test-only: the probe's fixture samples and its render guard. No renderer, no published surface, so the frontmatter is empty by design rather than scored — the explicit exemption this repo's changeset-presence gate names.
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
os-warren
marked this pull request as ready for review
August 24, 2026 02:55
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#3840
The
reading 'map'error card thatobject-formandobject-master-detail-formpaint under the binding-reach probe is a fixture defect (a), not a product defect (b). No renderer is touched.How the fork was resolved
Stopping at "the crash went away when I changed the sample" does not discriminate — that is true under both readings. So the discriminating step was the input's spec shape:
Bisected the generated schema. Printing what
sampleForbuilds and dropping inputs one at a time isolatessections. The stack names the read exactly —ObjectForm.tsx:1166, insideSimpleObjectForm:The generic
arraysample is the bare string['name'], sosectionis a string andsection.fieldsisundefined.Read whether the spec permits that value — the step that decides it. It does not:
sections: ['name']@objectstack/specFormViewSchema.sectionsREJECT— "Invalid input: expected object, received string"; and[{}]→ "0.fields: expected array, received undefined"packages/types/src/objectql.tsObjectFormSectionfields: (string | FormField)[]— required, on an object entry:242:266:293:325:355:1166).fields/.name/.labeloff each entrySo
['name']is not metadata any author could publish — publish-time validation rejects it. The fixture was handing the form family a plausible value that is not a plausible configuration, which is the lesson this file already counted four times.The block-props overlay (
ComponentPropsMap['object-form'].sections) isz.array(z.unknown())and accepts[42],[null], anything — worth stating because it is the schema nearest to hand and it cannot answer this question.FormViewSchemais the one that carries the authoring contract.object-master-detail-formno longer crashed on today'smain— but only by accidentThe card's premise is half stale, and the stale half is the more interesting one. That block declares
formTypeas a barestring(not the enumobject-formdeclares), so the generic sample was'x'— and the crashing loop is gated onObjectForm.tsx:1134:'x'skips it. Measured: withsectionsleft malformed, forcingformType: 'simple'reproduces the identicalreading 'map'crash. The block was green for a reason unrelated to its correctness, so itsformTypesample is corrected too — a value outside a prop's vocabulary routes around the block instead of exercising it. Filed separately as #5939.What changed — one file, plus the changeset
sampleForgets two name-keyed samples:sections→[{ name, label, fields: ['name'] }], andformType→'simple'. Keyed by name because the type carries no information here (sectionsandfieldsare botharray; only one is an array of objects).assertRenderedand moved ahead of the branch split, covering all 14 candidates — the shape the sibling proberecord-block-record-reach.test.tsxhas had from the start. The in-code comment that deferred this to [finding]object-form与object-master-detail-form在 binding-reach 探针的自动 fixture 下渲染成错误卡(reading 'map')—— 断言仍成立,但两个分支的崩溃守卫因此没法一起开 #3840 is gone, replaced by the reasoning for why a crash mis-reads on both branches (on the ledgered branch it confirms the ledger entry; on the other it points at wiring that is fine).Reverse-verification — the guard is load-bearing
Direction predicted before running: reverting only the
sectionssample should redden exactly two tests, via the new guard rather than the reach assertion. Observed exactly that:(The assertion message wraps the block name in angle brackets; they are stripped here because GitHub's body sanitizer eats short angle-bracket fragments.)
Both failures come from
assertRendered, not from the reach assertion — which confirms the card's "no false green today" claim: those blocks were always earning their data-reach verdicts, and it is the crash that was invisible. The mutation was confirmed on disk before the run (probe_sectionoccurrences 1 → 0, marker present, non-emptygit diff --stat) and restored by anEXIT/INT/TERMtrap.Gates — by name, at
58dda7a(the pushed commit; tree clean)vitest run apps/console/src/__tests__/Test Files 19 passed (19)/Tests 242 passed (242)@object-ui/console type-checktsc --noEmit && tsc -b tsconfig.node.json --force; script name echoed, so not a zero-match pass)@object-ui/console lint0occurrences ofanyin the added lines)check-changeset-presence.mjscheck-changeset-fixed.mjscheck-changeset-no-major.mjsmajorbump."check-control-bytes.mjsEvery exit code was captured before any pipe. The console's dependency closure was built first (
pnpm --filter '@object-ui/console^...' build) — without ittype-checkreports 40+ phantomTS2882module-resolution errors.Declared narrowing: lint was run for
@object-ui/consolerather than repo-wideturbo run lint. The narrowing is measured, not assumed: the surveyed population comes from eslint's own config resolution (eslint .in that package), the count is read from--format json(171 files), andeslint.config.jsenables no type-aware linting (noprojectService, noparserOptions.project) — so a diff confined to one file in this package cannot move any untouched file's verdict. CI runs the full farm regardless.Scope
One test file and one changeset. No renderer, no
apps/console/src/sdui-workbench-preview.tsx, nopackages/app-shell/src/views/**— the fork resolved to (a), so the conditional renderer half of the file surface never opened, and nothing here reaches #5458's files.Two out-of-scope findings were filed unassigned and both remain open, addressed by no change in this PR: #5939 (the
formTypedeclaration divergence above) and #5940 (object-master-detail-formcallsgetObjectSchema(undefined)for a detail collection it never resolved).Generated by Claude Code