google/gson · error · IllegalArgumentException

Cannot override built-in adapter for {type}

Error message

Cannot override built-in adapter for {type}

What it means

Thrown by registerTypeAdapter when type == Object.class. Gson's hasNonOverridableAdapter reserves Object.class for its internal reflective Object adapter and will not let a user replace it, because doing so would break deserialization of arbitrary object graphs.

Source

Thrown at gson/src/main/java/com/google/gson/GsonBuilder.java:754

   *     class or {@link JsonElement} or any of its subclasses
   * @see #registerTypeHierarchyAdapter(Class, Object)
   */
  @CanIgnoreReturnValue
  public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
    Objects.requireNonNull(type);
    Objects.requireNonNull(typeAdapter);
    if (!(typeAdapter instanceof JsonSerializer<?>
        || typeAdapter instanceof JsonDeserializer<?>
        || typeAdapter instanceof InstanceCreator<?>
        || typeAdapter instanceof TypeAdapter<?>)) {
      throw new IllegalArgumentException(
          "Class "
              + typeAdapter.getClass().getName()
              + " does not implement any supported type adapter class or interface");
    }

    if (hasNonOverridableAdapter(type)) {
      throw new IllegalArgumentException("Cannot override built-in adapter for " + type);
    }

    if (typeAdapter instanceof InstanceCreator<?>) {
      instanceCreators.put(type, (InstanceCreator<?>) typeAdapter);
    }
    if (typeAdapter instanceof JsonSerializer<?> || typeAdapter instanceof JsonDeserializer<?>) {
      TypeToken<?> typeToken = TypeToken.get(type);
      factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
    }
    if (typeAdapter instanceof TypeAdapter<?>) {
      @SuppressWarnings({"unchecked", "rawtypes"})
      TypeAdapterFactory factory =
          TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter) typeAdapter);
      factories.add(factory);
    }
    return this;
  }

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Register the adapter against a concrete base type, not Object.class.
  2. For polymorphic hierarchies use registerTypeHierarchyAdapter(MyBase.class, adapter) with a specific base class or interface.
  3. To influence all serialization, add a TypeAdapterFactory via registerTypeAdapterFactory and let it return null for types you do not own.
  4. If you need RuntimeTypeAdapterFactory-style polymorphism, register on the declared supertype.

Example fix

// before
gsonBuilder.registerTypeAdapter(Object.class, new MyObjectAdapter());
// after
gsonBuilder.registerTypeHierarchyAdapter(MyBase.class, new MyBaseAdapter());
Defensive patterns

Strategy: validation

Validate before calling

// Block reserved types before registering
java.lang.reflect.Type type = Object.class;
if (type == Object.class) {
  throw new IllegalArgumentException("Cannot register adapter for Object.class; use a concrete base type");
}
gsonBuilder.registerTypeAdapter(type, adapter);

Type guard

boolean isOverridableType(java.lang.reflect.Type t) { return t != Object.class; }

Prevention

When it happens

Trigger: Calling gsonBuilder.registerTypeAdapter(Object.class, adapter) for any adapter type, regardless of whether the adapter itself is valid.

Common situations: Trying to globally customize serialization of every object; migrating code from an older Gson usage that relied on overriding Object; attempting to intercept all polymorphic values.

Related errors


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