Code Beautifier
json: cannot unmarshal number 18.25 into Go struct field Order.total of type int64

Fix "cannot unmarshal number 18.25 into Go struct field"

The JSON has a fractional number but the Go field is int64. Why a whole-number sample produced the wrong type, and how to widen it to float64.

Input that triggers it

[{"total": 18}, {"total": 18.25}]
Open JSON to Go on its own page
Draft saved locally.

Local workspace

Named projects in IndexedDB · Local only — never synced to our servers. Worksp

Open manager

Batch workspace

Format multiple files locally in one run.

json
Go structsgo

What the error means

JSON has one number type. Go has many, and encoding/json will not silently truncate. json: cannot unmarshal number 18.25 into Go struct field Order.total of type int64 means the payload carried a value with a fractional part, and the struct field cannot represent it. Go refuses rather than rounding, which is the correct behaviour for a value that might be money.

The interesting part is how the field came to be int64 in the first place. In the example, the first record has "total": 18, a whole number, and the second has 18.25. A struct generated from only the first record gets int64; the second record then fails at runtime.

Why it happens

  • The sample was not representative. A single record, or a handful in which every value happened to be whole, produces an integer field for a quantity that is really a decimal.
  • Prices and measurements in particular are often whole in test data and fractional in production.
  • A percentage or a ratio that is usually 1 or 0 but occasionally 0.5.
  • A large integer that the producer serialised in exponent form (1e6), which some encoders emit for round numbers and which encoding/json treats as a float.

How to fix it

  1. Paste several records into the generator above, including one with a fractional value. It merges every item in the array, and it widens a field to float64 the moment any sample is fractional — that is precisely what a single-record sample cannot tell it.
  2. Change the field in your existing struct to float64.
  3. If the value is money, consider the alternative: have the producer send integer minor units (1825 cents) and keep int64. Floating-point arithmetic on currency is its own class of bug.
  4. If the number can be either an integer or a float and you need to know which, decode into json.Number and inspect the string.

The struct the merged sample produces:

type Root struct {
	Total float64 `json:"total"`
}

If it still fails

  • The same mismatch in Rust reads invalid type: floating point \18.25`, expected i64, and in C# The JSON value could not be converted to System.Int32`. JSON to Rust and JSON to C# apply the same widening rule when given a fractional sample.
  • If the field is int and the value is a whole number too large for it (9007199254740993 and above on 32-bit int), the message is about range, not fractions; use int64.
  • A struct generated from documentation rather than data is the usual root cause. Generate from a real capture.

Related errors