Repository navigation
fix(json_schema): make prefixItems entries positional per Draft 2020-12 - #834
Merged
Seven-Streams merged 2 commits intoAug 31, 2026
Merged
Conversation
feiiiiii5
requested review from
DarkSharpness,
Seven-Streams and
Ubospica
as code owners
August 14, 2026 12:05
4 tasks done
GenerateArray forced the full prefixItems sequence, so arrays shorter than the prefix were rejected (e.g. [] and [a] for a two-item prefix), and elements past a truncated prefix could leak into the additional-items tail. Build the array content as an alternation of the full prefix (plus the additional tail) and every shorter truncation, with the first min(minItems, n) entries still mandatory. Fixes mlc-ai#824. Signed-off-by: fei <[email protected]>
The truncation alternatives each repeated the mandatory head and the
shared prefix of the remaining items, so an n-item prefix expanded to
O(n^2) rule references. Replace the alternation with a right-recursive
chain suffix_k ::= "" | sep item_k suffix_{k+1} ending in the
additional-items tail, so each position is encoded once. Position 0,
when it is not part of the mandatory head, gets its own rule without
the separator. Also condenses the block comment.
The accepted language is unchanged; the full Python test suite passes.
Signed-off-by: fei <[email protected]>
Seven-Streams
force-pushed
the
fix/prefix-items-positional-824
branch
from
August 29, 2026 14:57
3f99770 to
83f1125
Compare
Seven-Streams
approved these changes
Aug 31, 2026
This was referenced Nov 1, 2026
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 free
to 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.
Root Cause
GenerateArraybuilt the prefix asSequence(prefix_elements), forcing everyprefixItemsentry to appear. Per JSON Schema Draft 2020-12,prefixItemsentries are positional — an instance may validly end after any prefix position (subject tominItems) — so arrays shorter than the prefix were wrongly rejected ([]and["a"]for a two-item prefix), and with a naive optional-chain fix the additional-items tail could absorb prefix positions (issue #824).Fix
Build the array content as an alternation of the full prefix (plus the additional tail) and every shorter truncation, keeping the first
min(minItems, n)entries mandatory:Additional items are only reachable after the complete prefix, so a mismatch inside the prefix range can never be rescued by the additional-items path. Truncations are plain sequences (no optional-chain backtracking), which keeps the grammar unambiguous.
Test
tests/python/test_json_schema_converter.py:test_prefix_items_truncated_prefix_accepted: the issue's accept-set matrix (1111 for[],["a"],["a",1],["a",1,true]withitems: {}), using the discriminating empty/one-element fixtures.test_prefix_items_min_items_forces_prefix_head:minItemsstill forces the head of the prefix.test_prefix_items_no_additional_items_allows_shorter:items: falseforbids elements beyond the prefix but must not force the full length.test_non_strict,test_array_schemaadditionalItems/unevaluatedItems cases,test_array_schema_min_max): shorter prefixes now accepted, wrong-position values still rejected.tests/pythonsuite 3253 passed (694 skipped, HF_TOKEN-gated),ruff checkclean, black 24.1.0 / clang-format 19.1.7 clean.Diff scope
2 files, +115/-20 (
cpp/json_schema_converter.ccGenerateArrayblock;tests/python/test_json_schema_converter.py).AI Disclosure
Root-cause analysis and the first optional-chain draft were AI-assisted; that draft over-accepted (additional items absorbing prefix positions), which was caught by the regression matrix and replaced with the truncation-alternation construction. The final patch was built and verified locally (cmake+ninja, full python suite) and human-reviewed before submission.
Fixes #824