google/gson · error · IllegalStateException

Please begin an object before writing a name.

Error message

Please begin an object before writing a name.

What it means

Thrown by JsonWriter.name() (JsonWriter.java:504-507) when the current scope is not EMPTY_OBJECT or NONEMPTY_OBJECT, i.e. you are trying to write a property name outside an object. JSON names are only valid inside objects, so calling name() at the document root or inside an array is rejected.

Solutions

  1. Call beginObject() before any name(); ensure the scope is an object when emitting names.
  2. Move the beginObject() call to a place guaranteed to run before the first name().
  3. Inside arrays, write values (or nested beginObject/beginArray), not names.
  4. At the document root, write a single value or open one object/array before names.

Example fix

// before
writer.name("a").value(1); // throws: no object open

// after
writer.beginObject();
writer.name("a").value(1);
writer.endObject();
Defensive patterns

Strategy: validation

Validate before calling

writer.beginObject();
try {
  writer.name("a").value(1);
} finally {
  writer.endObject();
}

Type guard

// Track current scope in your serializer.
boolean inObject = false;
void ensureObject() throws IOException {
  if (!inObject) { writer.beginObject(); inObject = true; }
}

Try / catch

try {
  writer.name("a").value(1);
} catch (IllegalStateException e) {
  // missing beginObject; restructure rather than catch
  throw e;
}

Prevention

When it happens

Trigger: Calling name() before beginObject(); calling name() inside an array (where values, not names, are expected); calling name() at the top level of the document.

Common situations: Serializers that write field names without opening an object first; mis-ordered calls in hand-written serializers; conditional beginObject() that was skipped on a branch but name() still called.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/dc330d9fd2d008b2. Report an issue: GitHub.

Appendix: source

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

  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;
    }
  }

  /**
   * Encodes {@code value}.
   *
   * @param value the literal string value, or null to encode a null literal.
   * @return this writer.

View on GitHub (pinned to 310ac341f2)