Go

What does this print? How do you preserve large integer precision when decoding unknown JSON?

Question 452HardGo 1.22 to 1.25
var m map[string]any
json.Unmarshal([]byte(`{"id": 12345678901234567890, "n": 1}`), &m)
fmt.Printf("%T %v\n", m["n"], m["id"])
_, ok := m["n"].(int)
fmt.Println(ok)

Output:

float64 1.2345678901234567e+19
false

Decoding into any maps JSON numbers to float64, objects to map[string]any, arrays to []any. A type assertion to int fails, and integers above 253 silently lose precision — a classic bug with Twitter/Snowflake IDs.

Fixes: decode into a typed struct with int64/uint64, or use Decoder.UseNumber() so numbers become json.Number (a string) which you convert explicitly:

dec := json.NewDecoder(strings.NewReader(`{"id": 12345678901234567890}`))
dec.UseNumber()
var m map[string]any
if err := dec.Decode(&m); err != nil {
	log.Fatal(err)
}
num := m["id"].(json.Number)
u, err := strconv.ParseUint(num.String(), 10, 64)
fmt.Println(u, err) // 12345678901234567890 <nil>

json.Number can also be used as a struct field type to accept numbers whose type you decide later.

More on Standard Library, HTTP & Systems Design in Go

All 35 Standard Library, HTTP & Systems Design in Go questions