google/gson · error · IllegalStateException
Array must have size 1, but has size {size}
Error message
Array must have size 1, but has size {size} What it means
Thrown by JsonArray.getAsSingleElement, which backs every getAsXxx convenience accessor on JsonArray (getAsInt, getAsString, getAsDouble, getAsBoolean, etc.). It requires the array to contain exactly one element; empty arrays or arrays with two or more elements raise IllegalStateException.
Source
Thrown at gson/src/main/java/com/google/gson/JsonArray.java:240
/**
* Returns the i-th element of the array.
*
* @param i the index of the element that is being sought.
* @return the element present at the i-th index.
* @throws IndexOutOfBoundsException if {@code i} is negative or greater than or equal to the
* {@link #size()} of the array.
*/
public JsonElement get(int i) {
return elements.get(i);
}
private JsonElement getAsSingleElement() {
int size = elements.size();
if (size == 1) {
return elements.get(0);
}
throw new IllegalStateException("Array must have size 1, but has size " + size);
}
/**
* Convenience method to get this array as a {@link Number} if it contains a single element. This
* method calls {@link JsonElement#getAsNumber()} on the element, therefore any of the exceptions
* declared by that method can occur.
*
* @return this element as a number if it is single element array.
* @throws IllegalStateException if the array is empty or has more than one element.
*/
@Override
public Number getAsNumber() {
return getAsSingleElement().getAsNumber();
}
/**
* Convenience method to get this array as a {@link String} if it contains a single element. This
* method calls {@link JsonElement#getAsString()} on the element, therefore any of the exceptionsView on GitHub (pinned to 8b8628c656)
Solutions
- Check jsonArray.size() == 1 before calling any getAsXxx accessor.
- For known-shape arrays, index explicitly with jsonArray.get(0).getAsInt() after a bounds check.
- Handle empty arrays explicitly (default value or skip) and multi-element arrays by iterating.
- If the field is genuinely a list, deserialize to List<T> rather than calling a scalar accessor on the JsonArray.
Example fix
// before
JsonArray arr = obj.getAsJsonArray("value");
int n = arr.getAsInt(); // throws if size != 1
// after
JsonArray arr = obj.getAsJsonArray("value");
if (arr.size() == 1) {
int n = arr.get(0).getAsInt();
} else {
// handle empty / multi-element
} Defensive patterns
Strategy: validation
Validate before calling
// Validate size before the scalar accessor
JsonArray arr = obj.getAsJsonArray("v");
if (arr.size() != 1) {
throw new IllegalStateException("expected single-element array, got " + arr.size());
}
int n = arr.getAsInt(); Type guard
boolean isSingleElement(JsonArray a) { return a != null && a.size() == 1; } Try / catch
// Guard against variable server shapes
JsonArray arr = obj.optJsonArray("v");
int n = (arr != null && arr.size() == 1) ? arr.get(0).getAsInt() : -1; Prevention
- Treat getAsXxx on JsonArray as a narrow contract: exactly one element.
- Prefer List<T> deserialization for genuinely list-shaped data.
- Add size() checks when an upstream API can return [] or [a,b].
When it happens
Trigger: Calling jsonArray.getAsInt()/getAsString()/getAsDouble()/getAsBoolean()/getAsNumber()/getAsLong()/getAsBigDecimal()/... on a JsonArray whose size() is 0 or >= 2.
Common situations: An API field that is usually a single value but is modeled as a JSON array and occasionally returns [] or multiple entries; deserializing a list field into a scalar accessor; a server version change that started returning arrays where it used to return scalars.
Related errors
- Not a JSON Object: {this}
- Not a JSON Array: {this}
- Not a JSON Primitive: {this}
- Not a JSON Null: {this}
- {getClass().getSimpleName()}
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/77d1fb067b652f9a.json.
Report an issue: GitHub.