{"record":{"id":"4d98415481e404f8","repo":"google/gson","slug":"dangling-name","errorCode":null,"errorMessage":"Dangling name: {}","messagePattern":"Dangling name: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/stream/JsonWriter.java","lineNumber":461,"sourceCode":"\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;\n  }\n\n  /** Returns the value on the top of the stack. */","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/stream/JsonWriter.java#L443-L479","documentation":"Thrown by JsonWriter.closeScope() (JsonWriter.java:460-462) when deferredName is non-null at the moment of closing a scope. A non-null deferredName means name() was called but no value was written yet; closing the object/array here would emit a name with no value, producing invalid JSON, so the writer rejects it.","triggerScenarios":"Calling name(\"x\") and then immediately endObject() or endArray() without an intervening value/nullValue call. Also conditional serializers that emit a name and then skip the value on a branch.","commonSituations":"Conditional field serialization that writes the name before checking whether to skip the value; serializers that emit a name then hit an exception path that closes the object; refactors that move the value write behind a flag.","solutions":["Always write a value (or nullValue()) after name(); if the value should be omitted, do not call name() at all.","Decide whether to serialize a field before calling name().","If you started a name you cannot complete, emit nullValue() to keep the JSON valid, or restructure to avoid the dangling name.","Set serializeNulls consistently if you rely on nullValue() to fill the slot."],"exampleFix":"// before\nwriter.beginObject();\nwriter.name(\"opt\");\nif (hasOpt) writer.value(v);\nwriter.endObject(); // dangling name when !hasOpt\n\n// after\nwriter.beginObject();\nif (hasOpt) {\n  writer.name(\"opt\").value(v);\n}\nwriter.endObject();","handlingStrategy":"validation","validationCode":"writer.beginObject();\nif (shouldWriteOpt) {\n  writer.name(\"opt\").value(v);\n}\nwriter.endObject();","typeGuard":"// Decide before calling name() whether a value will follow.\nboolean willEmitValue = (v != null && shouldSerialize);\nif (willEmitValue) writer.name(\"opt\").value(v);","tryCatchPattern":"try {\n  writer.endObject();\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"Dangling name\")) {\n    writer.nullValue(); // make JSON valid, then close\n    writer.endObject();\n  } else throw e;\n}","preventionTips":["Never call name() unless you are certain a value will follow.","Decide field inclusion before emitting the name.","Add tests for conditional-field serialization branches."],"tags":["java","gson","jsonwriter","state-machine","serialization"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}