google/gson · error · IllegalStateException
Array must have size 1, but has size
Error message
Array must have size 1, but has size ${size} What it means
Thrown by JsonArray.getAsSingleElement() (an internal helper used by getAsNumber, getAsString, getAsBoolean, etc.) when the array does not contain exactly one element. These convenience coercion methods are only well-defined for a single-element array; an empty or multi-element array is ambiguous and raises an IllegalStateException naming the actual size.
Solutions
- Check jsonArray.size() == 1 before calling getAsNumber/getAsString/etc.
- If multiple elements are valid, iterate the array and handle each, or pick an explicit index with get(i).
- Treat size == 0 as the missing/null case explicitly.
- Validate the JSON shape upstream (producer should send a scalar, not an array, when one value is expected).
Example fix
// before
JsonArray a = jsonObj.getAsJsonArray("score");
String s = a.getAsString(); // size != 1 -> throws
// after
JsonArray a = jsonObj.getAsJsonArray("score");
String s = a.size() == 1 ? a.get(0).getAsString() : null; Defensive patterns
Strategy: validation
Validate before calling
// Guard single-element coercion on a JsonArray
JsonArray a = element.getAsJsonArray();
if (a.size() != 1) {
throw new IllegalStateException("Expected single-element array, got size " + a.size());
}
String s = a.get(0).getAsString(); Try / catch
try { String s = array.getAsString(); }
catch (IllegalStateException e) {
if (e.getMessage().startsWith("Array must have size 1")) {
// iterate, pick an index, or treat as missing
} else throw e;
} Prevention
- Always check jsonArray.size() before single-value coercion methods.
- Handle empty arrays explicitly as a missing/null case.
- If multiple values are valid, iterate or index explicitly with get(i).
When it happens
Trigger: Calling getAsNumber()/getAsString()/getAsBoolean() (etc.) on a JsonArray with zero or with two+ elements; assuming a JSON array always wraps a single scalar; parsing an array-typed value through a single-value coercion path.
Common situations: API that sometimes returns an array of values where the consumer expects one; empty arrays for missing data; parsing config that uses arrays inconsistently; off-by-one index assumptions.
Related errors
- Attempted to deserialize a java.lang.Class. Forgot to…
- Cannot allocate . Usage of JDK sun.misc.Unsafe is enabled…
- cannot deserialize because it does not define a field named
- cannot deserialize subtype named ; did you forget to…
- Cannot parse ; at path
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/8169fa8e4fd8765d.
Report an issue: GitHub.
Appendix: 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 310ac341f2)