google/gson · error · NumberFormatException
Expected an int but was " + peekedString + locationString()
Error message
Expected an int but was " + peekedString + locationString()
What it means
Thrown by JsonReader.nextInt() as a NumberFormatException on the fallback path: the value could not be parsed as an int directly (Integer.parseInt failed) and either Double.parseDouble failed (rethrown at line 1371) or the double value loses precision when cast to int (line 1377). The message echoes the offending literal string.
Source
Thrown at gson/src/main/java/com/google/gson/stream/JsonReader.java:1377
// Fall back to parse as a double below.
}
} else {
throw unexpectedTokenError("an int");
}
peeked = PEEKED_BUFFERED;
double asDouble;
try {
asDouble = Double.parseDouble(peekedString);
} catch (NumberFormatException e) {
NumberFormatException rethrown =
new NumberFormatException("Expected an int but was " + peekedString + locationString());
rethrown.initCause(e);
throw rethrown;
}
result = (int) asDouble;
if (result != asDouble) { // Make sure no precision was lost casting to 'int'.
throw new NumberFormatException("Expected an int but was " + peekedString + locationString());
}
peekedString = null;
peeked = PEEKED_NONE;
pathIndices[stackSize - 1]++;
return result;
}
/**
* Closes this JSON reader and the underlying {@link Reader}.
*
* <p>Using the JSON reader after it has been closed will throw an {@link IllegalStateException}
* in most cases.
*/
@Override
public void close() throws IOException {
peeked = PEEKED_NONE;
stack[0] = JsonScope.CLOSED;
stackSize = 1;View on GitHub (pinned to 8b8628c656)
Solutions
- Use nextString() and parse with Integer.parseInt / NumberFormat yourself, handling failures explicitly.
- Use nextDouble() if the value can be fractional.
- Sanitize the data source to emit integer literals only.
- peek() first; if the token is a STRING, decide whether to coerce or skip.
Example fix
// before int n = reader.nextInt(); // throws for "1.5" or "abc" // after String raw = reader.nextString(); int n = Integer.parseInt(raw); // or NumberFormat.getInstance().parse(raw).intValue()
Defensive patterns
Strategy: validation
Validate before calling
// If the field may be a string or non-integer, read as string and parse defensively
String raw = reader.nextString();
try {
return Integer.parseInt(raw);
} catch (NumberFormatException e) {
double d = Double.parseDouble(raw);
return (int) d; // or handle as needed
} Try / catch
try {
return reader.nextInt();
} catch (NumberFormatException e) {
// log and apply a default, or re-read from the underlying source
return defaultValue;
} Prevention
- When producers may emit numbers as strings, read with nextString() and parse explicitly.
- Use nextDouble() if fractional values are valid for the field.
- Sanitize or reject non-numeric content in numeric fields at the source.
- peek() first and branch on JsonToken.STRING vs NUMBER.
When it happens
Trigger: Calling nextInt() on a quoted string like "abc", a fractional number "1.5", or a value that parses as a double but does not equal its int truncation. Also when the token is a numeric string that is not a valid number at all.
Common situations: Numeric fields that occasionally contain non-numeric or floating-point content; lenient JSON where numbers arrive as strings; schema mismatches; debug/test data with placeholder strings.
Related errors
- Expected a long but was " + peekedString + locationString()
- Expected an int but was " + peekedLong + locationString()
- Array must have size 1, but has size {size}
- Not a JSON Object: {this}
- Not a JSON Array: {this}
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/69823b111c05897e.json.
Report an issue: GitHub.