google/gson · error · NumberFormatException
Expected a long but was " + peekedString + locationString()
Error message
Expected a long but was " + peekedString + locationString()
What it means
Thrown by JsonReader.nextLong() as a NumberFormatException when the next token's value could be parsed as a double but loses precision when cast to long. This path is reached after the literal fails Long.parseLong but Double.parseDouble succeeds; the check `result != asDouble` detects the precision loss at JsonReader.java:1125.
Source
Thrown at gson/src/main/java/com/google/gson/stream/JsonReader.java:1126
// Fall back to parse as a double below.
}
} else {
throw unexpectedTokenError("a long");
}
peeked = PEEKED_BUFFERED;
double asDouble;
try {
asDouble = Double.parseDouble(peekedString);
} catch (NumberFormatException e) {
NumberFormatException rethrown =
new NumberFormatException("Expected a long but was " + peekedString + locationString());
rethrown.initCause(e);
throw rethrown;
}
long result = (long) asDouble;
if (result != asDouble) { // Make sure no precision was lost casting to 'long'.
throw new NumberFormatException("Expected a long but was " + peekedString + locationString());
}
peekedString = null;
peeked = PEEKED_NONE;
pathIndices[stackSize - 1]++;
return result;
}
/**
* Returns the string up to but not including {@code quote}, unescaping any character escape
* sequences encountered along the way. The opening quote should have already been read. This
* consumes the closing quote, but does not include it in the returned string.
*
* @param quote either ' or ".
*/
private String nextQuotedValue(char quote) throws IOException {
// Like nextNonWhitespace, this uses locals 'p' and 'l' to save inner-loop field access.
char[] buffer = this.buffer;
StringBuilder builder = null;View on GitHub (pinned to 8b8628c656)
Solutions
- Use nextDouble() if the value can legitimately be fractional, then convert yourself.
- Fix the data source to emit integer literals representable as long.
- Use nextString() and parse with BigInteger/BigDecimal if values may exceed long range.
- Read with nextLong() only after confirming via peek() that the token is a NUMBER without a decimal/exponent.
Example fix
// before long id = reader.nextLong(); // throws for "1.5" or 1e20 // after double d = reader.nextDouble(); long id = (long) d; // or use BigDecimal for arbitrary precision
Defensive patterns
Strategy: validation
Validate before calling
// Check token shape before nextLong
if (reader.peek() == JsonToken.NUMBER) {
// still may be fractional; read as string and test
String s = reader.nextString();
if (s.indexOf('.') >= 0 || s.indexOf('e') >= 0 || s.indexOf('E') >= 0) {
// not an integer literal; handle accordingly
} else {
long v = Long.parseLong(s);
}
} Try / catch
try {
return reader.nextLong();
} catch (NumberFormatException e) {
// fall back to double or BigInteger parsing of the field
return fallbackParseLong(reader);
} Prevention
- Use nextLong() only for fields known to be integer literals within long range.
- Switch to nextDouble() or nextString()+BigDecimal for values that may be fractional or oversized.
- Validate the JSON schema/producer to emit integer literals for integer fields.
- Read large IDs as strings to avoid precision loss across platforms.
When it happens
Trigger: Calling nextLong() on a JSON value like 1.5, 1e10 (if not representable exactly as long), or a quoted string "12345678901234567890" whose double value does not equal its long truncation. The reader reads it as a double, casts to long, sees they differ, and throws.
Common situations: JSON sources that emit fractional numbers where the consumer expects integers; scientific-notation numbers; very large numeric IDs serialized as strings or doubles; schema mismatches between producer and consumer.
Related errors
- Expected an int but was " + peekedLong + locationString()
- Expected an int but was " + peekedString + locationString()
- Failed parsing '" + s + "' as BigDecimal; at path " + in.get
- Failed parsing '" + s + "' as BigInteger; at path " + in.get
- Invalid nesting limit: " + limit
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/e688810e8ac1005e.json.
Report an issue: GitHub.