Repository navigation
fix(translator): treat contentSchema and unevaluatedItems as schema slots - #13110
Merged
diegosouzapw merged 2 commits intoSep 10, 2026
Merged
diegosouzapw merged 2 commits into
diegosouzapw merged 2 commits into
Conversation
…lots
stripInvalidSchemaConstructs() replaces a truncation placeholder with the
permissive {} in every position where a subschema belongs, because forwarding
the string is invalid JSON Schema and is the 400 the sanitizer exists to
prevent. SCHEMA_SLOT_KEYS listed ten of the draft 2020-12 applicators and
missed two, so a placeholder in either fell through to the scalar branch at
the bottom of the walker and was forwarded as a string:
items, additionalProperties, propertyNames, contains, not,
if, then, else, unevaluatedProperties, additionalItems -> {}
contentSchema, unevaluatedItems -> "[MaxDepth]"
The repository already disagrees with itself here: the opencode plugin's own
walker (@omniroute/opencode-plugin-v2/src/shared/gemini.ts) lists both under
SCHEMA_VALUE_KEYS, "keys whose value is itself a schema".
Nothing else about the two changes: an object or array in either position was
already recursed into by the fallback, a boolean is still preserved rather
than widened to {}, and a string that is not a placeholder is still forwarded
untouched.
diegosouzapw
merged commit Sep 10, 2026
0a314c8
into
cheaper-inference:release/v3.8.51
9 of 16 checks passed
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…lots (cheaper-inference#13110) Boarded with 13 sibling PRs into one worktree off release/v3.8.51 and validated as a set: 132 focused tests pass across all 15 test files in the batch, typecheck:core is clean, check-changelog-integrity reports no lost base bullets, and check-file-size is green. Your PR merged without conflict against its siblings. Thank you — the write-up made this reviewable: measuring the behaviour on the release tip and showing the before/after table meant the defect could be confirmed rather than taken on faith.
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.
The bug
stripInvalidSchemaConstructs()replaces a truncation placeholder with the permissive{}in every position where a subschema belongs. Forwarding the string instead is invalid JSON Schema, and that 400 is the thing this sanitizer exists to prevent.SCHEMA_SLOT_KEYSlisted ten of the draft 2020-12 applicators and missed two. Measured onrelease/v3.8.51, feeding{ type: "object", [key]: "[MaxDepth]" }through the walker one keyword at a time:items,additionalProperties,propertyNames,contains,not,if,then,else,unevaluatedProperties,additionalItems{}contentSchema"[MaxDepth]"unevaluatedItems"[MaxDepth]"Those two fall through to the scalar branch at the bottom of the walker — the one that deliberately leaves annotation keywords (
description,title,pattern,format) as strings — and are forwarded untouched.The placeholders are real:
logTruncation.tsemits[MaxDepth],[Truncated],[Circular],[Object]and[Array]once a schema is deeper than the log depth limit, andSCHEMA_PLACEHOLDER_PATTERNhere matches all five.The repository already disagrees with itself
The opencode plugin's own walker lists both:
Two lists of the same thing, kept in step by hand. They agreed on ten entries and diverged on two, and nothing failed when they did — both files compile, both walkers answer, they just answer differently.
The change
Two entries. Nothing else about those keywords changes: an object or array in either position was already recursed into by the fallback branch, a boolean is still preserved rather than widened to
{}(contentSchema: falseis restrictive and must stay so), and a string that is not a placeholder is still forwarded untouched.Tests
tests/unit/translator/schema-slot-keys-drift.test.ts, 17 tests. Rather than testing the two new keywords alone, it drives all twelve slots through all five placeholder shapes, so the next keyword to go missing fails here too. It also pins the three properties that keep the fix from being a widening: booleans preserved, non-placeholder strings untouched, and a property namedcontentSchemastill treated as a property.unevaluatedItemsThe second mutation matters: it shows the coverage test is not an all-or-nothing check.
tests/unit/translator/schema-coercion.test.ts,bailian-schema-validation,agentSkills-schemas— 32 passed.eslint --suppressions-location config/quality/eslint-suppressions.jsonclean.Independent of #13101 and #13104; different files.