Skip to content

Preserve integer precision in AdditionalProperties via UseNumber#4095

Open
charlie-zhang109 wants to merge 2 commits into
masterfrom
charlie.zhang/use-UseNumber
Open

Preserve integer precision in AdditionalProperties via UseNumber#4095
charlie-zhang109 wants to merge 2 commits into
masterfrom
charlie.zhang/use-UseNumber

Conversation

@charlie-zhang109
Copy link
Copy Markdown

Fixes #4091.

Summary

The generated UnmarshalJSON for every model with an additionalProperties block populates AdditionalProperties map[string]interface{} via datadog.Unmarshal, which is a thin wrapper around encoding/json.Unmarshal. The standard Go decoder unmarshals JSON numbers into interface{} targets as float64, so integers above 2^53 silently lose precision. Typed schema fields decode into concrete *int64 targets and are not affected.

This PR switches the additionalProperties decode to a UseNumber-enabled decoder via a new datadog.UnmarshalUseNumber helper.

Changes

  • .generator/src/generator/templates/encoding_json.j2 — add UnmarshalUseNumber to the stdlib JSON backend.
  • .generator/src/generator/templates/goccy_gojson.j2 — add UnmarshalUseNumber to the goccy_gojson backend.
  • .generator/src/generator/templates/model_simple.j2 — one-line change: the additionalProperties decode now calls datadog.UnmarshalUseNumber instead of datadog.Unmarshal.

Templates-only — happy to regenerate the rendered output into the same PR if reviewers prefer that.

Behavioral contract change

After regeneration, values in AdditionalProperties will be json.Number (string-backed) rather than float64.

  • Callers using val.(float64) will break.
  • Callers using val.(json.Number).Int64() or .Float64() get correct precision.

Suggest changelog/Changed + backward-incompatible labels.

Test plan

  • Regenerate output via the apigentools flow and confirm the diff in api/datadog/encoding_json.go, api/datadog/goccy_gojson.go, and the ~100+ affected model_*.go files matches expectation.
  • CI on the regenerated PR (unit tests + cassette-based integration tests).
  • Targeted unit test: round-trip an integer > 2^53 through a model with additionalProperties and assert exact recovery via .(json.Number).Int64(). Happy to write this — flag if you'd like it in this PR or as a follow-up.

JSON integers above 2^53 silently lost precision when the value landed
in a generated model's AdditionalProperties map. The generated
UnmarshalJSON populated that map via datadog.Unmarshal
(encoding/json.Unmarshal), which coerces JSON numbers into float64 for
interface{} targets.

Switch the additionalProperties decode in model_simple.j2 to a
UseNumber-enabled decoder via a new datadog.UnmarshalUseNumber helper
(added to encoding_json.j2 and goccy_gojson.j2 for both JSON backends).
Typed schema fields and existing decode paths are unaffected.

After regeneration, values in AdditionalProperties are json.Number
(string-backed) rather than float64. Callers can recover the original
integer via .(json.Number).Int64().

Fixes #4091.
@charlie-zhang109 charlie-zhang109 requested review from a team as code owners May 15, 2026 16:39
@charlie-zhang109 charlie-zhang109 added changelog/Changed Changed features results into a major version bump backward-incompatible Warns for backward incompatible changes labels May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backward-incompatible Warns for backward incompatible changes changelog/Changed Changed features results into a major version bump

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Silent precision loss for JSON integers > 2^53 decoded into AdditionalProperties

1 participant