{"record":{"id":"a7c483b0a9761c85","repo":"google/gson","slug":"already-wrote-a-name-expecting-a-value","errorCode":null,"errorMessage":"Already wrote a name, expecting a value.","messagePattern":"Already wrote a name, expecting a value\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/stream/JsonWriter.java","lineNumber":502,"sourceCode":"    return stack[stackSize - 1];\n  }\n\n  /** Replace the value on the top of the stack with the given value. */\n  private void replaceTop(int topOfStack) {\n    stack[stackSize - 1] = topOfStack;\n  }\n\n  /**\n   * Encodes the property name.\n   *\n   * @param name the name of the forthcoming value. May not be {@code null}.\n   * @return this writer.\n   */\n  @CanIgnoreReturnValue\n  public JsonWriter name(String name) throws IOException {\n    Objects.requireNonNull(name, \"name == null\");\n    if (deferredName != null) {\n      throw new IllegalStateException(\"Already wrote a name, expecting a value.\");\n    }\n    int context = peek();\n    if (context != EMPTY_OBJECT && context != NONEMPTY_OBJECT) {\n      throw new IllegalStateException(\"Please begin an object before writing a name.\");\n    }\n    deferredName = name;\n    return this;\n  }\n\n  private void writeDeferredName() throws IOException {\n    if (deferredName != null) {\n      beforeName();\n      string(deferredName);\n      deferredName = null;\n    }\n  }\n\n  /**","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/stream/JsonWriter.java#L484-L520","documentation":"Thrown by JsonWriter.name() (JsonWriter.java:501-503) when deferredName is already set, i.e. name() was called twice in a row without a value in between. JSON object members are name:value pairs, so two consecutive names would be invalid; the writer stores the name in deferredName and flushes it only when a value (or nullValue) is written.","triggerScenarios":"Calling writer.name(\"a\").name(\"b\") with no value between them; a loop that emits names without writing values; serializers that conditionally call name() twice on the same field.","commonSituations":"Loop bodies that always call name() but skip the value on some iterations; copy-paste of a name() call; refactors that moved the value write out of the name() block.","solutions":["Always write a value (or nullValue()) immediately after each name().","Restructure loops so each iteration emits a complete name/value pair.","Guard name() calls so you never call it twice without an intervening value.","Add a serializer test that detects double-name sequences."],"exampleFix":"// before\nwriter.beginObject();\nfor (String k : keys) {\n  writer.name(k);\n}\nwriter.endObject(); // second name() throws\n\n// after\nwriter.beginObject();\nfor (String k : keys) {\n  writer.name(k).value(map.get(k));\n}\nwriter.endObject();","handlingStrategy":"validation","validationCode":"writer.beginObject();\nfor (Map.Entry<String,V> e : map.entrySet()) {\n  writer.name(e.getKey()).value(e.getValue());\n}\nwriter.endObject();","typeGuard":"// Ensure exactly one value follows each name within a single code block.\nassert deferredValueEmitted : \"name without value\";","tryCatchPattern":"try {\n  writer.name(\"x\").name(\"y\");\n} catch (IllegalStateException e) {\n  // programming error; fix the serializer, do not swallow\n  throw e;\n}","preventionTips":["Always chain name().value(...) in the same statement when possible.","Review loop bodies to confirm each name() has a paired value.","Add serializer tests that emit multiple fields."],"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-23T08:17:48.524Z"}