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

  1. Inspect the literal at the reported path and correct the source.
  2. Tighten strictness to STRICT so malformed numbers fail earlier with a clearer message.
  3. Register a custom TypeAdapter for the numeric field that handles the offending format.
  4. 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

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


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