google/gson · error · IllegalStateException
Nesting problem.
Error message
Nesting problem.
What it means
Thrown by JsonWriter.closeScope() (used by endArray/endObject) when the current scope on the stack is neither the matching empty nor nonempty scope. This indicates mismatched begin/end calls, e.g. calling endArray() when an object is currently open, or calling endObject() twice.
Source
Thrown at gson/src/main/java/com/google/gson/stream/JsonWriter.java:458
public JsonWriter endObject() throws IOException {
return closeScope(EMPTY_OBJECT, NONEMPTY_OBJECT, '}');
}
/** Enters a new scope by appending any necessary whitespace and the given bracket. */
@CanIgnoreReturnValue
private JsonWriter openScope(int empty, char openBracket) throws IOException {
beforeValue();
push(empty);
out.write(openBracket);
return this;
}
/** Closes the current scope by appending any necessary whitespace and the given bracket. */
@CanIgnoreReturnValue
private JsonWriter closeScope(int empty, int nonempty, char closeBracket) throws IOException {
int context = peek();
if (context != nonempty && context != empty) {
throw new IllegalStateException("Nesting problem.");
}
if (deferredName != null) {
throw new IllegalStateException("Dangling name: " + deferredName);
}
stackSize--;
if (context == nonempty) {
newline();
}
out.write(closeBracket);
return this;
}
private void push(int newTop) {
if (stackSize == stack.length) {
stack = Arrays.copyOf(stack, stackSize * 2);
}
stack[stackSize++] = newTop;View on GitHub (pinned to 8b8628c656)
Solutions
- Audit every beginObject/beginArray to ensure a matching endObject/endArray on every code path (use try-finally).
- Build the structure first in memory and serialize, or use Gson's tree model, to avoid manual balancing.
- Add unit tests that round-trip the writer output through a JsonReader to catch imbalance.
- Use a state-tracking wrapper that asserts begin/end symmetry.
Example fix
// before
writer.beginObject();
if (cond) {
writer.endArray(); // wrong: should be endObject(), or no end at all
}
// after
writer.beginObject();
try {
// ... write fields
} finally {
writer.endObject();
} Defensive patterns
Strategy: validation
Validate before calling
// Use a wrapper that balances begin/end on every path
JsonWriter w = ...;
w.beginObject();
try {
// write fields
} finally {
w.endObject();
}
// or assert symmetry in tests by round-tripping the produced JSON Prevention
- Pair every beginObject()/beginArray() with a matching end in a try-finally.
- Use Gson's POJO serialization or tree model to avoid manual scope balancing.
- Add round-trip tests (write then read back) to catch imbalance.
- Avoid mixing beginObject/beginArray within the same conditional branch.
When it happens
Trigger: Calling endArray() after beginObject() (or vice versa), or calling an end method without a corresponding begin, or emitting more end calls than begins. The scope mismatch is detected at JsonWriter.java:457.
Common situations: Branching serialization logic where one path emits an extra end or skips one; manual writer use with conditionals that forget to balance brackets; refactoring tree-building code and losing a begin/end pairing.
Related errors
- Please begin an object before writing a name.
- Already wrote a name, expecting a value.
- Dangling name: " + deferredName
- rawType must be of type Class, but was " + rawType
- JsonWriter is closed.
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/a228fe1914c7db9c.json.
Report an issue: GitHub.