Skip to content

fix(schema): emit min/max constraints for applicable type kinds#2975

Merged
schani merged 2 commits into
masterfrom
agent/fix-issue-2557
Jul 21, 2026
Merged

fix(schema): emit min/max constraints for applicable type kinds#2975
schani merged 2 commits into
masterfrom
agent/fix-issue-2557

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Bug

Reported in #2557: converting a JSON Schema through quicktype's
--src-lang schema ... --lang schema round trip silently dropped
minLength/maxLength (on strings) and minimum/maximum (on
numbers/integers) from the output schema, while pattern and
description survived correctly. Since the schema-to-schema pass is the
first stage of every other output language too, this also meant the
constraints never reached downstream generators (TypeScript, zod, etc.).

Root cause

MinMaxConstraintTypeAttributeKind.addToSchema in
packages/quicktype-core/src/attributes/Constraints.ts had an inverted
applicability guard:

if (this._typeKinds.has(t.kind)) return;

_typeKinds holds the type kinds a given constraint kind actually
applies to ({"integer", "double"} for min/max value, {"string"} for
min/max length). As written, the method bailed out and skipped emitting
the constraint into the schema exactly when the type's kind was
applicable — the opposite of the intended behavior. Compare with
PatternTypeAttributeKind.addToSchema, which has the correct polarity
(if (t.kind !== "string") return;) and is why pattern round-tripped
fine while minLength/maxLength/minimum/maximum did not.

Fix

Inverted the guard:

if (!this._typeKinds.has(t.kind)) return;

This is a one-line change; the zod/TypeScript renderers not emitting
these constraints into generated validation code is a separate, unrelated
missing feature and is out of scope for this PR.

Test coverage

  • Added a new schema-schema fixture (test/fixtures/schema/main.js)
    that validates the round-tripped JSON Schema output against the
    original sample using AJV, registered in test/languages.ts /
    test/fixtures.ts.
  • Added test/inputs/schema/schema-constraints.schema with:
    • schema-constraints.1.json — a sample that satisfies
      minLength/maxLength/minimum/maximum.
    • schema-constraints.{1,2}.fail.minmaxlength.json — samples that
      violate minLength/maxLength and must be rejected by the
      generated schema.
    • schema-constraints.{3,4}.fail.minmax.json — samples that violate
      minimum/maximum and must be rejected by the generated schema.

These fail samples only pass once the generated schema actually contains
the constraints, so they reproduce the bug on unfixed code and verify the
fix.

Verification (local)

  • npm run build — passes.
  • QUICKTEST=true FIXTURE=schema-schema script/test — 68/68 passed
    (including the new schema-constraints.schema cases).
  • npm run test:unit — 163/163 tests passed across 25 files.
  • Manually re-ran the reporter's repro
    (node dist/index.js --src-lang schema bad-schema.json --lang schema)
    and confirmed minLength/maxLength/minimum/maximum are now
    present in the generated schema.
  • Full multi-language fixture suite (FIXTURE=schema, all
    schema-<lang> targets) is left to CI, since several target-language
    toolchains (e.g. dotnet) aren't available in this environment.

Fixes #2557

🤖 Generated with Claude Code

schani and others added 2 commits July 20, 2026 16:44
The applicability guard in MinMaxConstraintTypeAttributeKind.addToSchema
was inverted: it skipped emitting minimum/maximum/minLength/maxLength
exactly when the type's kind WAS applicable, so schema-to-schema
round-trips silently dropped these constraints (pattern and description
were unaffected since PatternTypeAttributeKind used the correct polarity).

Added a schema-schema fixture (test/fixtures/schema/main.js) that
validates round-tripped JSON Schema output with AJV, plus
test/inputs/schema/schema-constraints.schema with pass/fail samples
exercising minLength/maxLength/minimum/maximum, which fail before this
fix and pass after it.

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
cjson declares the minmax/minmaxlength features so the fail samples run,
but its generated code does not enforce min/max/length constraints — which
is why it already skips minmax.schema, minmaxlength.schema, pattern.schema
and optional-constraints.schema. The new schema-constraints.schema is the
same kind of constraint fixture and was never added to the skip list, so
its expected-failure samples were not rejected and schema-cjson failed.
Scope it out for cjson alongside the existing constraint schemas.

Co-Authored-By: Claude <noreply@anthropic.com>
@schani
schani merged commit 55ec1d1 into master Jul 21, 2026
28 checks passed
@schani
schani deleted the agent/fix-issue-2557 branch July 21, 2026 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Certain schema attributes are not generated into code

1 participant