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

  1. Check jsonArray.size() == 1 before calling getAsNumber/getAsString/etc.
  2. If multiple elements are valid, iterate the array and handle each, or pick an explicit index with get(i).
  3. Treat size == 0 as the missing/null case explicitly.
  4. 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

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


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 exceptions

View on GitHub (pinned to 310ac341f2)