Skip to content

jsonschema: schema decoding rounds const and enum numbers before validation #83

Open

Description

@Tangerg

On main at 794ce5e (also observed with v0.4.3), decoding a schema can silently change the numeric values in const and enum before validation.

For example:

var s jsonschema.Schema
json.Unmarshal([]byte(`{"const":9007199254740993}`), &s)
r, _ := s.Resolve(nil)
fmt.Println(r.Validate(json.Number("9007199254740993"))) // rejected
fmt.Println(r.Validate(json.Number("9007199254740992"))) // accepted

The schema re-marshals as {"const":9007199254740992}. The same issue affects enum values, nested objects/arrays, negative large integers, and precise decimal numbers. A constraint such as 1e400 fails to decode altogether because of the float64 conversion.

Expected: schema constraints retain their JSON numeric values, so the original value validates and a different value does not. Tests reproduce both incorrect rejection and incorrect acceptance without using a type keyword.

This is distinct from #80 / #81: those concern classification of an instance's json.Number. Here the schema's own constant has already changed. The existing exact comparison code can compare these values correctly if schema decoding preserves them.

Proposed fix: use json.Decoder.UseNumber when decoding schema values into any, including the separate explicit-null-aware Const path. Keep concrete numeric fields (such as Minimum *float64) unchanged; their precision limits need a separate API discussion. This changes dynamic types in decoded Const/Enum/Examples/Extra values from float64 to json.Number, and should be reviewed as a behavioral compatibility change.

Environment: Go 1.27.0, darwin/arm64. A companion protocol-boundary issue is modelcontextprotocol/go-sdk#1310.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions