google/gson · error · JsonSyntaxException
Expecting number, got: ${jsonToken}; at path ${path}
Error message
Expecting number, got: ${jsonToken}; at path ${path} What it means
NumberTypeAdapter handles fields/variables typed as Number. Its read() accepts only NULL, NUMBER, or STRING (numeric) tokens; any other token (BOOLEAN, BEGIN_OBJECT, BEGIN_ARRAY, NAME, END_*) is a type mismatch and Gson throws JsonSyntaxException with the offending token and the reader path. This guards against silently coercing incompatible JSON into a numeric Java field.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/NumberTypeAdapter.java:73
if (toNumberStrategy == ToNumberPolicy.LAZILY_PARSED_NUMBER) {
return LAZILY_PARSED_NUMBER_FACTORY;
} else {
return newFactory(toNumberStrategy);
}
}
@Override
public Number read(JsonReader in) throws IOException {
JsonToken jsonToken = in.peek();
switch (jsonToken) {
case NULL:
in.nextNull();
return null;
case NUMBER:
case STRING:
return toNumberStrategy.readNumber(in);
default:
throw new JsonSyntaxException(
"Expecting number, got: " + jsonToken + "; at path " + in.getPath());
}
}
@Override
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
}
View on GitHub (pinned to 310ac341f2)
Solutions
- Fix the source data to send a numeric JSON value for Number-typed fields
- Register a custom TypeAdapter<Number> that coerces or nulls incompatible tokens
- Deserialize the field as Object and post-process, or use a more permissive target type
Example fix
// before - boolean where Number expected
{"count": true}
// after - numeric value
{"count": 1} Defensive patterns
Strategy: type-guard
Validate before calling
// Inspect the token before binding a Number field
JsonReader reader = ...;
JsonToken t = reader.peek();
if (t == JsonToken.NUMBER || t == JsonToken.STRING || t == JsonToken.NULL) {
Number n = gson.fromJson(reader, Number.class);
} else {
// schema drift: handle, default, or skip
reader.skipValue();
} Type guard
// Narrow a JsonElement to a numeric value before binding
static boolean isNumeric(JsonElement e) {
return e != null && e.isJsonPrimitive() && e.getAsJsonPrimitive().isNumber();
} Try / catch
try {
Number n = gson.fromJson(json, Number.class);
} catch (com.google.gson.JsonSyntaxException e) {
// 'Expecting number, got: <token>': source sent a non-numeric; coerce or skip
} Prevention
- Validate the JSON token type for Number fields before deserialization
- Register a custom TypeAdapter<Number> to coerce or null invalid tokens
- Pin down producer schemas so numeric fields never carry other types
When it happens
Trigger: Deserializing JSON where a Number-typed field receives a boolean, object, or array; e.g. {"count": true} mapped to a Number field, or {"amount": {}} where a number was expected.
Common situations: Schema drift where a numeric field arrives as a different JSON type; weakly-typed Object payloads later narrowed to Number; producer bugs emitting the wrong value type.
Related errors
- Unexpected token: ${peeked}
- String contains non-ASCII characters: ${s} at path ${path}
- JSON forbids NaN and infinities: ${value}
- duplicate key: ${key}
- Failed to invoke constructor '${constructor}' with args ${ac
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/0caa9e97640c53f1.
Report an issue: GitHub.