Code Beautifier
json: cannot unmarshal string into Go struct field

Fix "json: cannot unmarshal string into Go struct field"

Go's encoding/json found a string where the struct declares a number, bool, or struct. Why the types disagree, and three ways to fix it.

Input that triggers it

{"id": "42", "active": "true"}
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

Go's encoding/json is strict about types. When it decodes a JSON value into a struct field, the JSON type and the Go type must be compatible: a JSON number into an int or float64, a JSON string into a string, a JSON bool into a bool. json: cannot unmarshal string into Go struct field User.id of type int means the payload carried a string for a field the struct declares as something else. The message names the struct, the field, and the Go type, which makes it one of the more helpful runtime errors.

In the example, id arrives as "42" and active as "true" — both strings. A struct generated from a sample where those were 42 and true will reject this payload, because the producer changed its mind about types.

Why it happens

  • The API sends numbers as strings. Common with IDs (to avoid 64-bit precision loss in JavaScript clients), money amounts, and anything that passed through a form or a query string.
  • The sample used to generate the struct had a different type than production data. One record with "id": 42 produces int; the real feed sends "42".
  • Booleans as "true"/"false" strings, or "yes"/"no", from a legacy backend.
  • A nested object arriving as a JSON-encoded string — the classic double-encoding bug, where a field contains "{\"a\":1}" instead of {"a":1}.

How to fix it

  1. Paste a representative payload into the generator above — the one that fails, not the one from the docs. It infers string for any field whose sample value is a string, and the generated struct will decode the real data.
  2. If the value is semantically a number and the producer will not change, keep the Go type and add the string option to the tag: ID int64 \json:"id,string"`. encoding/jsonthen accepts"42"for that field and still rejects"forty-two"`.
  3. For a field that may arrive as either type, decode into json.Number or json.RawMessage and convert explicitly.
  4. For a double-encoded object, unmarshal the outer document first, then unmarshal the string field's contents into the inner struct.

The struct that matches the example as sent:

type Root struct {
	ID     string `json:"id"`
	Active string `json:"active"`
}

If it still fails

  • Note which field the message names. If it is a nested struct field, the problem may be one level down: cannot unmarshal string into Go struct field Order.customer of type main.Customer means customer arrived as a string, not an object.
  • Validate the payload with JSON Validator to confirm the types you think are being sent are the types actually on the wire.
  • The same payload against a TypeScript interface fails silently rather than loudly; JSON to TypeScript shows what a permissive typing of the same data looks like.

Related errors