google/gson · error · JsonSyntaxException
Failed parsing '" + s + "' as BigDecimal; at path " + in.get
Error message
Failed parsing '" + s + "' as BigDecimal; at path " + in.getPreviousPath()
What it means
Thrown by Gson's built-in BigDecimal TypeAdapter when the JSON token cannot be parsed by NumberLimits.parseBigDecimal. Gson reads the value as a string then delegates to BigDecimal parsing, so any non-numeric, malformed, or locale-specific number (e.g. with a comma) triggers a NumberFormatException that is wrapped into a JsonSyntaxException. The 'at path' suffix identifies the offending location in the JSON tree.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java:591
@Override
public void write(JsonWriter out, String value) throws IOException {
out.value(value);
}
};
public static final TypeAdapter<BigDecimal> BIG_DECIMAL =
new TypeAdapter<BigDecimal>() {
@Override
public BigDecimal read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String s = in.nextString();
try {
return NumberLimits.parseBigDecimal(s);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(
"Failed parsing '" + s + "' as BigDecimal; at path " + in.getPreviousPath(), e);
}
}
@Override
public void write(JsonWriter out, BigDecimal value) throws IOException {
out.value(value);
}
};
public static final TypeAdapterFactory BIG_DECIMAL_FACTORY =
newFactory(BigDecimal.class, BIG_DECIMAL);
public static final TypeAdapter<BigInteger> BIG_INTEGER =
new TypeAdapter<BigInteger>() {
@Override
public BigInteger read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {View on GitHub (pinned to 8b8628c656)
Solutions
- Inspect the 'at path' location in your JSON and correct the offending value to plain numeric syntax (dot decimal, no separators).
- Sanitize the string before Gson deserialization, e.g. strip currency symbols and replace commas with dots.
- Register a custom TypeAdapter<BigDecimal> that pre-cleans or falls back gracefully on malformed input.
- Use Gson's setLenient()/object-mapping to accept the value as String first, then convert manually.
Example fix
// before
Gson gson = new Gson();
BigDecimal price = gson.fromJson(json, BigDecimal.class);
// after: tolerate locale-formatted numbers
Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(BigDecimal.class, new JsonDeserializer<BigDecimal>() {
@Override public BigDecimal deserialize(JsonElement j, Type t, JsonDeserializationContext c) {
String s = j.getAsString().replace(".", "").replace(",", ".").trim();
return s.isEmpty() ? BigDecimal.ZERO : new BigDecimal(s);
}
}).create(); Defensive patterns
Strategy: validation
Validate before calling
boolean isParsableBigDecimal(String s) {
if (s == null || s.isEmpty()) return false;
try { new BigDecimal(s); return true; } catch (NumberFormatException e) { return false; }
} Type guard
static boolean isBigDecimalString(JsonElement el) {
return el != null && el.isJsonPrimitive() && el.getAsJsonPrimitive().isString()
&& el.getAsString().matches("[+-]?(\\d+(\\.\\d+)?|\\.\\d+)");
} Try / catch
try {
BigDecimal v = gson.fromJson(json, BigDecimal.class);
} catch (JsonSyntaxException e) {
// log the path from e.getMessage(), fall back to null or a sentinel
} Prevention
- Validate numeric strings with a regex or trial-parse before handing them to Gson.
- Define a schema/contract for BigDecimal fields (plain decimal, dot separator, no symbols).
- Register a single normalization TypeAdapter<BigDecimal> at Gson construction rather than patching call sites.
When it happens
Trigger: Deserializing a JSON value into a BigDecimal field/element where the source string is not valid BigDecimal syntax (letters, multiple dots, thousands separators like '1,234.5', trailing spaces, empty string, or a JSON boolean/object).
Common situations: European locale data with decimal commas, upstream API returning null-as-empty-string, mismatch between producer locale and consumer expectations, numbers in scientific notation that exceed configured limits, or a field typed as BigDecimal but populated with a currency symbol.
Related errors
- Failed parsing '" + s + "' as BigInteger; at path " + in.get
- duplicate key: {key}
- Expecting number, got: " + jsonToken + "; at path " + in.get
- Unexpected token: " + peeked
- Failed parsing '" + s + "' as UUID; at path " + in.getPrevio
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/652c3579e3863535.json.
Report an issue: GitHub.