Code Beautifier
invalid type: string "42", expected i64

Fix serde "invalid type: string, expected i64"

The payload sends a number as a string; serde will not coerce it. The fixes: change to String, write a deserializer, or use serde_with's DisplayFromStr.

Input that triggers it

{"id": "42", "count": 3}
Open JSON to Rust 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
Rustrust

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

  1. Paste a representative payload into the generator above. If id is a string in the sample, the field is emitted as String. If it is a string in some records and a number in others, the field becomes serde_json::Value so nothing is rejected.
  2. If the value is an identifier — you never do arithmetic on it — String is the honest type. Change the field.
  3. If it is genuinely a number that happens to arrive quoted, keep i64 and tell serde how to parse it. The serde_with crate's DisplayFromStr does 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,
}
  1. Without an extra dependency, write a small deserialize_with function 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 says String` 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 ,string tag 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