{"id":"239e9240286bbd15","repo":"google/gson","slug":"did-not-expect-a-name","errorCode":null,"errorMessage":"Did not expect a name","messagePattern":"Did not expect a name","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/bind/JsonTreeWriter.java","lineNumber":150,"sourceCode":"  @Override\n  public JsonWriter endObject() throws IOException {\n    if (stack.isEmpty() || pendingName != null) {\n      throw new IllegalStateException();\n    }\n    JsonElement element = peek();\n    if (element instanceof JsonObject) {\n      stack.remove(stack.size() - 1);\n      return this;\n    }\n    throw new IllegalStateException();\n  }\n\n  @CanIgnoreReturnValue\n  @Override\n  public JsonWriter name(String name) throws IOException {\n    Objects.requireNonNull(name, \"name == null\");\n    if (stack.isEmpty() || pendingName != null) {\n      throw new IllegalStateException(\"Did not expect a name\");\n    }\n    JsonElement element = peek();\n    if (element instanceof JsonObject) {\n      pendingName = name;\n      return this;\n    }\n    throw new IllegalStateException(\"Please begin an object before writing a name.\");\n  }\n\n  @CanIgnoreReturnValue\n  @Override\n  public JsonWriter value(String value) throws IOException {\n    if (value == null) {\n      return nullValue();\n    }\n    put(new JsonPrimitive(value));\n    return this;\n  }","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/bind/JsonTreeWriter.java#L132-L168","documentation":"Thrown by JsonTreeWriter.name() when the stack is empty (no container is open) or when pendingName is already non-null (a previous name() has not yet been consumed by a value). JSON object members must alternate name then value; a second name without an intervening value, or a name with no enclosing object, is illegal.","triggerScenarios":"Calling name() twice in a row inside an object without writing a value between them; calling name() before any beginObject(); calling name() on a writer that just consumed a value and is back to expecting a name but pendingName is somehow still set (double-name bug).","commonSituations":"Serializer loop that emits name() then conditionally skips the value but still advances; copy-paste leaving two name() calls adjacent; serializer that writes name() at the top level instead of inside beginObject()/endObject().","solutions":["Ensure exactly one value (or container) follows every name() before the next name().","Wrap name()+value() in a helper that always pairs them, so a skip can't leave a dangling name.","Only call name() between beginObject() and endObject(), never at top level.","Add a test exercising conditional fields to catch the dangling-name path."],"exampleFix":"// before: two name() calls in a row\nout.beginObject();\nout.name(\"a\");\nout.name(\"b\").value(2); // throws: Did not expect a name\nout.endObject();\n\n// after: pair each name with a value\nout.beginObject();\nout.name(\"a\").value(1);\nout.name(\"b\").value(2);\nout.endObject();","handlingStrategy":"validation","validationCode":"// Only call name() inside an open object, and only when no name is pending\nif (stackEmpty || pendingName != null) throw new IllegalStateException(\"name() not allowed here\");\nout.name(k);","typeGuard":null,"tryCatchPattern":"try {\n  out.name(k);\n} catch (IllegalStateException e) {\n  if (\"Did not expect a name\".equals(e.getMessage())) {\n    // likely: double name() or name() outside object; write a null value to recover\n    out.nullValue();\n    out.name(k);\n  } else throw e;\n}","preventionTips":["Always follow name() with exactly one value/container before the next name().","Wrap name()+value() in a helper that guarantees pairing.","Call name() only between beginObject() and endObject()."],"tags":["json","streaming","writer-state","gson","object-shape"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}