google/gson · error · JsonParseException
Cannot parse {value}; at path {in.getPreviousPath()}
Error message
Cannot parse {value}; at path {in.getPreviousPath()} What it means
In LAZILY_PARSED_NUMBER, when a numeric literal cannot be parsed by Long.parseLong and the fallback Double.valueOf throws NumberFormatException, Gson wraps it as JsonParseException with the offending literal and reader path. The token looked numeric to the reader but is not a valid Java number.
Source
Thrown at gson/src/main/java/com/google/gson/ToNumberPolicy.java:93
} else {
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
return parseAsDouble(value, in);
}
}
}
private Number parseAsDouble(String value, JsonReader in) throws IOException {
try {
Double d = Double.valueOf(value);
if ((d.isInfinite() || d.isNaN()) && !in.isLenient()) {
throw new MalformedJsonException(
"JSON forbids NaN and infinities: " + d + "; at path " + in.getPreviousPath());
}
return d;
} catch (NumberFormatException e) {
throw new JsonParseException(
"Cannot parse " + value + "; at path " + in.getPreviousPath(), e);
}
}
},
/**
* Using this policy will ensure that numbers will be read as numbers of arbitrary length using
* {@link BigDecimal}.
*/
BIG_DECIMAL {
@Override
public BigDecimal readNumber(JsonReader in) throws IOException {
String value = in.nextString();
try {
return NumberLimits.parseBigDecimal(value);
} catch (NumberFormatException e) {
throw new JsonParseException(
"Cannot parse " + value + "; at path " + in.getPreviousPath(), e);View on GitHub (pinned to 8b8628c656)
Solutions
- Inspect the literal at the reported path and correct the source.
- Tighten strictness to STRICT so malformed numbers fail earlier with a clearer message.
- Register a custom TypeAdapter for the numeric field that handles the offending format.
- Pre-validate numeric fields with a regex if the producer is unreliable.
Example fix
// before
// JSON: { "price": "1.299,50" } (locale grouping)
// after
// JSON: { "price": 1299.50 }
// or register a custom TypeAdapter stripping separators Defensive patterns
Strategy: try-catch
Validate before calling
if (!raw.matches("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?")) {
throw new IllegalArgumentException("bad number literal: " + raw);
}
Type guard
boolean isParsableJavaNumber(String s) {
try { Double.parseDouble(s); return true; }
catch (NumberFormatException ex) { return false; }
}
Try / catch
try {
return policy.readNumber(in);
} catch (JsonParseException ex) {
if (ex.getMessage().startsWith("Cannot parse")) {
// log literal + path, then return null or default
}
throw ex;
}
Prevention
- Tighten reader strictness to STRICT for fail-fast on malformed numbers.
- Validate numeric fields with a regex at the trust boundary.
- Normalize locale-specific separators upstream.
When it happens
Trigger: Numeric tokens with leading +, underscores, hex prefixes, locale-specific groupings, or truncated values; leniently accepted tokens like 1.2.3 reaching Double.valueOf; very malformed numbers slipped through a lenient reader.
Common situations: Hand-crafted JSON, locales using thousands separators, porting from Jackson (which may accept +N), corrupted transport truncating digits.
Related errors
- JSON forbids NaN and infinities: {d}; at path {in.getPreviou
- cannot deserialize {baseType} because it does not define a f
- cannot deserialize {baseType} subtype named {label}; did you
- {value}
- Invalid number: {value}
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/bc5e8bdd0434bbf8.json.
Report an issue: GitHub.