{"record":{"id":"a228fe1914c7db9c","repo":"google/gson","slug":"nesting-problem","errorCode":null,"errorMessage":"Nesting problem.","messagePattern":"Nesting problem\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/stream/JsonWriter.java","lineNumber":458,"sourceCode":"  public JsonWriter endObject() throws IOException {\n    return closeScope(EMPTY_OBJECT, NONEMPTY_OBJECT, '}');\n  }\n\n  /** Enters a new scope by appending any necessary whitespace and the given bracket. */\n  @CanIgnoreReturnValue\n  private JsonWriter openScope(int empty, char openBracket) throws IOException {\n    beforeValue();\n    push(empty);\n    out.write(openBracket);\n    return this;\n  }\n\n  /** Closes the current scope by appending any necessary whitespace and the given bracket. */\n  @CanIgnoreReturnValue\n  private JsonWriter closeScope(int empty, int nonempty, char closeBracket) throws IOException {\n    int context = peek();\n    if (context != nonempty && context != empty) {\n      throw new IllegalStateException(\"Nesting problem.\");\n    }\n    if (deferredName != null) {\n      throw new IllegalStateException(\"Dangling name: \" + deferredName);\n    }\n\n    stackSize--;\n    if (context == nonempty) {\n      newline();\n    }\n    out.write(closeBracket);\n    return this;\n  }\n\n  private void push(int newTop) {\n    if (stackSize == stack.length) {\n      stack = Arrays.copyOf(stack, stackSize * 2);\n    }\n    stack[stackSize++] = newTop;","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/stream/JsonWriter.java#L440-L476","documentation":"Thrown by JsonWriter.closeScope() (JsonWriter.java:456-459) when the current stack context is neither the matching empty nor nonempty scope for the bracket being closed, e.g. calling endArray() while the top of stack is an object scope (or vice versa). The writer tracks scopes on a stack and refuses to emit a closing bracket that would produce malformed JSON.","triggerScenarios":"Calling endArray() when the writer is inside an object (top scope EMPTY_OBJECT/NONEMPTY_OBJECT), or endObject() inside an array. Also calling end* more times than begin*, or mismatching nesting in recursive serializers.","commonSituations":"Hand-written serializers with unbalanced begin/end; conditional branches that call beginArray but skip endArray on an early return; copy-paste errors swapping endObject/endArray; serializers that delegate to sub-writers and mis-track the scope.","solutions":["Pair every beginArray with endArray and every beginObject with endObject, including in error/early-return paths.","Restructure serializers so begin and end are in the same method (try/finally).","Add unit tests asserting the produced JSON round-trips through a JsonReader.","Use a stack/depth counter in your serializer to validate balance before writing."],"exampleFix":"// before\nwriter.beginObject();\nwriter.name(\"a\").value(1);\nwriter.endArray(); // wrong scope\n\n// after\nwriter.beginObject();\nwriter.name(\"a\").value(1);\nwriter.endObject();","handlingStrategy":"validation","validationCode":"// Enforce balance in your serializer with try/finally.\nwriter.beginArray();\ntry {\n  for (T item : items) writeItem(writer, item);\n} finally {\n  writer.endArray();\n}","typeGuard":"// No public scope introspection on JsonWriter; track depth in your own serializer.\nclass BalancedWriter {\n  private int depth;\n  void beginArray() throws IOException { w.beginArray(); depth++; }\n  void endArray() throws IOException { w.endArray(); depth--; }\n}","tryCatchPattern":"try {\n  writer.endArray();\n} catch (IllegalStateException e) {\n  // scope mismatch: log and recover the document state, or fail fast\n  throw e;\n}","preventionTips":["Pair begin/end in the same method using try/finally.","Unit-test serializers with round-trip parse/emit.","Avoid conditional end* calls; structure code so they always run."],"tags":["java","gson","jsonwriter","nesting","state-machine"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}