What the error means
serde does not coerce between JSON types. A field declared i64 accepts a JSON number and nothing else; a JSON string — even "42" — is a type error: invalid type: string "42", expected i64 at line 1 column 11. The message quotes the value it found and names the type it wanted, and the position points at the end of the offending value.
In the example, id arrives as "42". A struct generated from a sample where id was 42 declares i64 and rejects this payload.
Why it happens
- The producer sends numbers as strings. IDs are the usual case, done deliberately to avoid 64-bit precision loss in JavaScript consumers; money amounts and timestamps as well.
- The generation sample had a number where production data has a string, so the inferred type is wrong for the real feed.
- A value that is a string in some records and a number in others — the generator turns that into
serde_json::Value, which is correct but loses typing. - Booleans as
"true"or numbers as"1e3"from a legacy system.
How to fix it
- Paste a representative payload into the generator above. If
idis a string in the sample, the field is emitted asString. If it is a string in some records and a number in others, the field becomesserde_json::Valueso nothing is rejected. - If the value is an identifier — you never do arithmetic on it —
Stringis the honest type. Change the field. - If it is genuinely a number that happens to arrive quoted, keep
i64and tell serde how to parse it. Theserde_withcrate'sDisplayFromStrdoes exactly this:
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
#[serde_as(as = "DisplayFromStr")]
pub id: i64,
pub count: i64,
}
- Without an extra dependency, write a small
deserialize_withfunction that accepts either a number or a string and parses accordingly.
If it still fails
- The mirror error,
invalid type: integer \42`, expected a string, means the struct saysString` and the payload sends a number; the same options apply in reverse. - Go reports the same mismatch as
cannot unmarshal string into Go struct field, and offers the,stringtag option for quoted numbers; JSON to Go covers it. - Check the wire format with JSON Validator — a quoted number in a log line is easy to misread as unquoted.
Related errors
missing field `email`
Make the field Option<String> (the generator does this when any sample omits the key) or add #[serde(default)] to fall back to a default value.
json: cannot unmarshal string into Go struct field
Make the struct field match the payload (string), or fix the producer to send a number; for numbers-as-strings, tag the field with `json:",string"` or unmarshal into json.Number.