google/gson · error · JsonSyntaxException

Failed parsing '" + s + "' as BigInteger; at path " + in.get

Error message

Failed parsing '" + s + "' as BigInteger; at path " + in.getPreviousPath()

What it means

Gson's BigInteger TypeAdapter reads the JSON token as a string and calls NumberLimits.parseBigInteger. Any value that is not a valid integer literal (decimal digits only, optional leading minus) throws NumberFormatException, which Gson wraps as JsonSyntaxException with the source string and JSON path.

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java:617

        }
      };

  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) {
            in.nextNull();
            return null;
          }
          String s = in.nextString();
          try {
            return NumberLimits.parseBigInteger(s);
          } catch (NumberFormatException e) {
            throw new JsonSyntaxException(
                "Failed parsing '" + s + "' as BigInteger; at path " + in.getPreviousPath(), e);
          }
        }

        @Override
        public void write(JsonWriter out, BigInteger value) throws IOException {
          out.value(value);
        }
      };

  public static final TypeAdapterFactory BIG_INTEGER_FACTORY =
      newFactory(BigInteger.class, BIG_INTEGER);

  public static final TypeAdapter<LazilyParsedNumber> LAZILY_PARSED_NUMBER =
      new TypeAdapter<LazilyParsedNumber>() {
        // Normally users should not be able to access and deserialize LazilyParsedNumber because
        // it is an internal type, but implement this nonetheless in case there are legit corner
        // cases where this is possible

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Fix the JSON to emit a plain integer literal (digits only, optional leading minus).
  2. Strip formatting characters (commas, spaces, '+') from the source string before deserialization.
  3. Register a custom TypeAdapter<BigInteger> that cleans or coerces the input.
  4. If the value legitimately has a fractional part, change the target type to BigDecimal.

Example fix

// before
BigInteger id = gson.fromJson("\"1,234,567\"", BigInteger.class);

// after
Gson gson = new GsonBuilder()
    .registerTypeHierarchyAdapter(BigInteger.class, new JsonDeserializer<BigInteger>() {
        @Override public BigInteger deserialize(JsonElement j, Type t, JsonDeserializationContext c) {
            String s = j.getAsString().replaceAll("[^0-9-]", "");
            return new BigInteger(s);
        }
    }).create();
Defensive patterns

Strategy: validation

Validate before calling

boolean isParsableBigInteger(String s) {
  if (s == null || s.isEmpty()) return false;
  try { new BigInteger(s); return true; } catch (NumberFormatException e) { return false; }
}

Type guard

static boolean isBigIntegerString(String s) {
  return s != null && s.matches("[+-]?\\d+");
}

Try / catch

try {
  BigInteger v = gson.fromJson(json, BigInteger.class);
} catch (JsonSyntaxException e) {
  // record path, fall back to null or sanitize and retry
}

Prevention

When it happens

Trigger: Deserializing into a BigInteger field where the JSON value contains a decimal point, exponent, non-digit characters, thousands separators, or is empty.

Common situations: Storing IDs as BigInteger but the producer emits them quoted with formatting, scientific notation from another serializer, decimal values accidentally mapped to an integer field, or empty/null-as-string from a flaky upstream.

Related errors


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/018057602e2cf06b.json. Report an issue: GitHub.