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

  1. Register an InstanceCreator or TypeAdapter for the failing type (especially for interfaces/abstract classes).
  2. Ensure the concrete target type is used for deserialization, or supply TypeToken capturing generics.
  3. If using reflection-heavy code, add Gson --add-opens / module opens or proguard keep rules for the type.
  4. 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

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


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