google/gson · error · IllegalArgumentException
GSON (${GsonBuildConfig.VERSION}) cannot handle ${type}
Error message
GSON (${GsonBuildConfig.VERSION}) cannot handle ${type} What it means
Thrown by Gson.getAdapter(TypeToken) when none of the registered factories (built-in + user) can produce a TypeAdapter for the requested type. After iterating every factory, if candidate is still null the type is deemed unhandleable and an IllegalArgumentException is thrown including the Gson version. This typically means the type is fundamentally unsupported or all adapters were stripped.
Source
Thrown at gson/src/main/java/com/google/gson/Gson.java:385
threadCalls.put(type, call);
for (TypeAdapterFactory factory : factories) {
candidate = factory.create(this, type);
if (candidate != null) {
call.setDelegate(candidate);
// Replace future adapter with actual adapter
threadCalls.put(type, candidate);
break;
}
}
} finally {
if (isInitialAdapterRequest) {
threadLocalAdapterResults.remove();
}
}
if (candidate == null) {
throw new IllegalArgumentException(
"GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
}
if (isInitialAdapterRequest) {
/*
* Publish resolved adapters to all threads
* Can only do this for the initial request because cyclic dependency TypeA -> TypeB -> TypeA
* would otherwise publish adapter for TypeB which uses not yet resolved adapter for TypeA
* See https://github.com/google/gson/issues/625
*/
typeTokenCache.putAll(threadCalls);
}
return candidate;
}
/**
* Returns the type adapter for {@code type}.
*View on GitHub (pinned to 310ac341f2)
Solutions
- Register an InstanceCreator or TypeAdapter for the failing type (especially for interfaces/abstract classes).
- Ensure the concrete target type is used for deserialization, or supply TypeToken capturing generics.
- If using reflection-heavy code, add Gson --add-opens / module opens or proguard keep rules for the type.
- Double-check that any custom TypeAdapterFactory.create() returns a non-null adapter for the types it claims.
Example fix
// before
gson.fromJson("{}", SomeInterface.class); // no adapter -> throws
// after
gson = new GsonBuilder()
.registerTypeAdapter(SomeInterface.class, (InstanceCreator<?>) t -> new SomeImpl())
.create(); Defensive patterns
Strategy: validation
Validate before calling
// Probe adapter availability before relying on it
TypeAdapter<?> a;
try {
a = gson.getAdapter(TypeToken.get(type));
} catch (IllegalArgumentException e) {
// type not handleable; register an InstanceCreator or TypeAdapter, or reject
throw new IllegalStateException("No adapter for " + type, e);
} Try / catch
try { gson.getAdapter(typeToken); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("cannot handle")) { /* register adapter or fallback */ }
else throw e;
} Prevention
- Always register InstanceCreators for interfaces/abstract classes.
- Use concrete types or TypeTokens that capture generics.
- Keep proguard/R8 --add-opens / keep rules for reflected types.
When it happens
Trigger: Requesting an adapter for a type that cannot be reflected or constructed (e.g. an interface with no InstanceCreator and no concrete binding); a custom TypeAdapterFactory returning null for a type it was supposed to handle; serializing/deserializing a type whose only adapter was a factory registered after it but skipped; types like Object.class used in contexts that bypass the built-in adapter.
Common situations: Deserializing into an abstract class/interface without an InstanceCreator; proguard/R8 stripping removes type info; misconfigured factory order; JDK module access restrictions blocking reflection on non-open types.
Related errors
- GSON cannot serialize or deserialize ${type}
- Type adapter '${typeAdapter}' returned wrong type; requested
- Adapter for type with cyclic dependency has been used before
- Class ${typeAdapter.getClass().getName()} does not implement
- Invalid attempt to bind an instance of ${className} as a @Js
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/35c025c89c7a8a15.
Report an issue: GitHub.