Fix JSON Schema prefixItems import semantics - #7060
Conversation
🦋 Changeset detectedLatest commit: 8aea002 The changes in this PR will be included in the next version bump. This PR includes changesets to release 30 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Important
The reproduction tests are correct and fail as expected against the current fromJsonSchemaDocument implementation, but this branch still needs the implementation fix before it can merge. CI is expected to remain red until collectArrayChecks and the tuple rest logic in packages/effect/src/internal/schema/fromJsonSchemaDocument.ts:759-820 are updated.
Reviewed changes
- Added a focused regression test in
packages/effect/test/schema/representation/fromJsonSchemaDocument.test.tsthat pins the expected semantics forprefixItemscombined withmaxItems: both the bounded form (reject arrays longer than the bound) and the open form (allow trailing items after the prefix up to the bound) are covered.
@v0 or keep the SHA fresh with Dependabot | Fix it ➔ | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Implemented the fix in
packages/effect/src/internal/schema/fromJsonSchemaDocument.ts:maxItemsis now enforced as an array-length bound except when it exactly matches the length of a closedprefixItemstuple. - Added a changeset describing the runtime behavior fix.
- The focused regression test added in the prior commit now passes.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|
0ee4c23 to
7bac144
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Refined
items: falsehandling soprefixItemstuples are closed withrest: []instead of aNeverrest element. - Extended
maxItemsredundancy detection to coveritems: falsewhen the bound is at least the prefix length. - Replaced the focused runtime behavior test with representation assertions inside the existing
prefixItemstest block.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
7bac144 to
8ac2a54
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Simplified the
isMaxItemsRedundantderivation inpackages/effect/src/internal/schema/fromJsonSchemaDocument.tsby computing it from the existingisTupleClosedflag; the resulting behavior is unchanged but the logic is easier to follow. - Refactored
packages/effect/test/schema/representation/fromJsonSchemaDocument.test.tsto split combinedfor-loop test cases into individualitblocks with more descriptive titles; assertions are preserved.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Summary
Importing
prefixItemswithmaxItemscan accept arrays longer thanmaxItemsand reject permitted trailing items when the bound exceeds the prefix length. The resulting Effect schema therefore disagrees with both bounded and open Draft 2020-12 tuple forms.Important
This PR starts with focused failing reproduction tests. Add the implementation fix to this same branch; CI is expected to fail until that fix is included.
JSON Schema prefixItems loses maxItems semantics
Module:
effect/internal/schema/fromJsonSchemaDocumentAudit ID:
effect-ff1a063c2ab0dc92Severity / confidence: medium / high
What happens
Importing
prefixItemswithmaxItemscan accept arrays longer thanmaxItemsand reject permitted trailing items when the bound exceeds the prefix length. The resulting Effect schema therefore disagrees with both bounded and open Draft 2020-12 tuple forms.Why it happens
The importer creates an element for every
prefixItemsentry, setsrestto empty whenever any numericmaxItemsis present, and suppressesmaxLengthchecks wheneverprefixItemsexists. Thus a bound shorter than the prefix is not enforced, while a bound longer than the prefix is converted into a closed tuple at the prefix length.Expected behavior
SchemaRepresentation.fromJsonSchemaDocumentmust treatprefixItemsas positional constraints,maxItemsas the total array-length bound, and absent or permissiveitemsas allowing values after the prefix up to that bound.Relevant implementation
These links and excerpts are pinned to audit base
17f0b91a243ccfe4a38d27debdc983adf434e738.packages/effect/src/internal/schema/fromJsonSchemaDocument.ts:759-820View problematic code at
packages/effect/src/internal/schema/fromJsonSchemaDocument.ts:759-808View exact lines on GitHub
Excerpt truncated. Open the complete packages/effect/src/internal/schema/fromJsonSchemaDocument.ts:759-820 range.
Reproduction
pnpm test --run packages/effect/test/schema/representation/fromJsonSchemaDocument.test.tsObserved failure: Focused contract assertion failed against 17f0b91, demonstrating: JSON Schema prefixItems loses maxItems semantics.
Implementation handoff
The initial reproduction tests on this branch are the regression specification for the implementation fix that should follow in this PR.
pnpm test --run packages/effect/test/schema/representation/fromJsonSchemaDocument.test.tsAudit provenance
17f0b91a243ccfe4a38d27debdc983adf434e73817f0b91a243ccfe4a38d27debdc983adf434e738effect-ff1a063c2ab0dc92Closes EFF-491