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
- Register the adapter against a concrete base type, not Object.class.
- For polymorphic hierarchies use registerTypeHierarchyAdapter(MyBase.class, adapter) with a specific base class or interface.
- To influence all serialization, add a TypeAdapterFactory via registerTypeAdapterFactory and let it return null for types you do not own.
- 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
- Never register against Object.class.
- Pick the most specific common supertype for hierarchy adapters.
- Document which types each adapter owns to avoid collisions with built-ins.
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
- Class {typeAdapter.getClass().getName()} does not implement
- GSON ({GsonBuildConfig.VERSION}) cannot handle {type}
- GSON cannot serialize or deserialize {type}
- Invalid style: {style}
- Invalid attempt to bind an instance of {className} as a @Jso
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/f54280ae8a372746.json.
Report an issue: GitHub.