google/gson · error · IllegalStateException

Already wrote a name, expecting a value.

Error message

Already wrote a name, expecting a value.

What it means

Thrown by JsonWriter.name() when deferredName is already non-null, meaning a previous name() was called but no value has been written yet. JSON objects require strictly alternating name/value pairs; two names in a row is invalid and would produce malformed output.

Source

Thrown at gson/src/main/java/com/google/gson/stream/JsonWriter.java:502

    return stack[stackSize - 1];
  }

  /** Replace the value on the top of the stack with the given value. */
  private void replaceTop(int topOfStack) {
    stack[stackSize - 1] = topOfStack;
  }

  /**
   * Encodes the property name.
   *
   * @param name the name of the forthcoming value. May not be {@code null}.
   * @return this writer.
   */
  @CanIgnoreReturnValue
  public JsonWriter name(String name) throws IOException {
    Objects.requireNonNull(name, "name == null");
    if (deferredName != null) {
      throw new IllegalStateException("Already wrote a name, expecting a value.");
    }
    int context = peek();
    if (context != EMPTY_OBJECT && context != NONEMPTY_OBJECT) {
      throw new IllegalStateException("Please begin an object before writing a name.");
    }
    deferredName = name;
    return this;
  }

  private void writeDeferredName() throws IOException {
    if (deferredName != null) {
      beforeName();
      string(deferredName);
      deferredName = null;
    }
  }

  /**

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Always pair name() with exactly one value write before the next name().
  2. Move name() inside the conditional so it is only emitted alongside its value.
  3. Track write state explicitly if using loops that may skip values.
  4. Use Gson's POJO serialization instead of manual name()/value() calls to avoid this class of bug.

Example fix

// before
writer.name("a");
if (cond) writer.value(1);
writer.name("b"); // throws if cond was false: 'Already wrote a name'

// after
if (cond) writer.name("a").value(1);
writer.name("b").value(2);
Defensive patterns

Strategy: validation

Validate before calling

// Track whether a value is pending before calling name() again
boolean nameWritten = false;
// always:
if (!nameWritten) {
  writer.name("x").value(v);
  // or set nameWritten=false after value
}

Prevention

When it happens

Trigger: Calling writer.name("a").name("b") without a value between them, or any logic where name() is invoked twice because a value write was conditionally skipped or reordered.

Common situations: Loop-based serialization where the name is written at the top of the loop but the value is sometimes skipped; refactoring that moves name() out of an if branch; copy-paste errors adding a duplicate name() call.

Related errors


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/a7c483b0a9761c85.json. Report an issue: GitHub.