google/gson · error · IllegalStateException
Not a JSON Array
Error message
Not a JSON Array: ${this} What it means
Thrown by JsonElement.getAsJsonArray() (JsonElement.java:178) as an IllegalStateException when the element is not a JsonArray. Returns (JsonArray) this only when isJsonArray() is true (this instanceof JsonArray); otherwise throws with the element's toString appended.
Solutions
- Guard with element.isJsonArray() (and null-check) before calling getAsJsonArray()
- If the API may return either a single object or an array, normalize both into a list
- Handle the null/JsonNull case explicitly
- Use a typed POJO (e.g. List<Item>) via gson.fromJson so Gson tolerates single-vs-list shapes
Example fix
// before
JsonArray items = root.get("items").getAsJsonArray();
// after
JsonElement e = root.get("items");
List<JsonElement> items = new ArrayList<>();
if (e != null && e.isJsonArray()) items = e.getAsJsonArray().asList();
else if (e != null && e.isJsonObject()) items.add(e);
// else: missing/null -> empty list Defensive patterns
Strategy: type-guard
Validate before calling
JsonElement e = root.get("items");
boolean safe = (e != null && e.isJsonArray()); Type guard
static JsonArray asArray(JsonElement e) {
return (e != null && e.isJsonArray()) ? e.getAsJsonArray() : new JsonArray();
} Try / catch
try {
JsonArray a = element.getAsJsonArray();
} catch (IllegalStateException ex) {
// message starts with "Not a JSON Array:"
} Prevention
- Null-check and call isJsonArray() before getAsJsonArray()
- For APIs that return a single object instead of a list, normalize both shapes into a list
- Use a typed List<T> target with gson.fromJson
When it happens
Trigger: Calling getAsJsonArray() on a JsonObject, JsonPrimitive, or JsonNull. Common: obj.get("items").getAsJsonArray() where 'items' is null, a single object, or a scalar; or an API that returns a single object instead of a list when the list has one element.
Common situations: API returns a bare object instead of a list for singleton results (a frequent serialization quirk); a field is conditionally null; mixed-type arrays where code assumes an array at a given path.
Related errors
- Not a JSON Null
- Not a JSON Object
- Not a JSON Primitive
- ${getClass().getSimpleName()}
- Primitive is neither a number nor a string
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/c3bf8230a1d95b61.
Report an issue: GitHub.
Appendix: source
Thrown at gson/src/main/java/com/google/gson/JsonElement.java:178
if (isJsonObject()) {
return (JsonObject) this;
}
throw new IllegalStateException("Not a JSON Object: " + this);
}
/**
* Convenience method to get this element as a {@link JsonArray}. If this element is of some other
* type, an {@link IllegalStateException} will result. Hence it is best to use this method after
* ensuring that this element is of the desired type by calling {@link #isJsonArray()} first.
*
* @return this element as a {@link JsonArray}.
* @throws IllegalStateException if this element is of another type.
*/
public JsonArray getAsJsonArray() {
if (isJsonArray()) {
return (JsonArray) this;
}
throw new IllegalStateException("Not a JSON Array: " + this);
}
/**
* Convenience method to get this element as a {@link JsonPrimitive}. If this element is of some
* other type, an {@link IllegalStateException} will result. Hence it is best to use this method
* after ensuring that this element is of the desired type by calling {@link #isJsonPrimitive()}
* first.
*
* @return this element as a {@link JsonPrimitive}.
* @throws IllegalStateException if this element is of another type.
*/
public JsonPrimitive getAsJsonPrimitive() {
if (isJsonPrimitive()) {
return (JsonPrimitive) this;
}
throw new IllegalStateException("Not a JSON Primitive: " + this);
}
View on GitHub (pinned to 310ac341f2)