{"id":"b8da59c354244f09","repo":"google/gson","slug":"gson-gsonbuildconfig-version-cannot-handle-ty","errorCode":null,"errorMessage":"GSON ({GsonBuildConfig.VERSION}) cannot handle {type}","messagePattern":"GSON \\((.+?)\\) cannot handle (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/Gson.java","lineNumber":385,"sourceCode":"      threadCalls.put(type, call);\n\n      for (TypeAdapterFactory factory : factories) {\n        candidate = factory.create(this, type);\n        if (candidate != null) {\n          call.setDelegate(candidate);\n          // Replace future adapter with actual adapter\n          threadCalls.put(type, candidate);\n          break;\n        }\n      }\n    } finally {\n      if (isInitialAdapterRequest) {\n        threadLocalAdapterResults.remove();\n      }\n    }\n\n    if (candidate == null) {\n      throw new IllegalArgumentException(\n          \"GSON (\" + GsonBuildConfig.VERSION + \") cannot handle \" + type);\n    }\n\n    if (isInitialAdapterRequest) {\n      /*\n       * Publish resolved adapters to all threads\n       * Can only do this for the initial request because cyclic dependency TypeA -> TypeB -> TypeA\n       * would otherwise publish adapter for TypeB which uses not yet resolved adapter for TypeA\n       * See https://github.com/google/gson/issues/625\n       */\n      typeTokenCache.putAll(threadCalls);\n    }\n    return candidate;\n  }\n\n  /**\n   * Returns the type adapter for {@code type}.\n   *","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/Gson.java#L367-L403","documentation":"Thrown by Gson.getAdapter(TypeToken) when NO registered TypeAdapterFactory (including Gson's built-in factories) returns a non-null adapter for the requested type. This means Gson has no way to serialize or deserialize the given type. The message embeds the running Gson version for support purposes. It is an IllegalArgumentException, typically surfaced from toJson/fromJson.","triggerScenarios":"Requesting an adapter for a type Gson inherently cannot handle (e.g. a class with no default constructor and no InstanceCreator, under configurations where reflection is blocked); a type fully excluded by reflection filters; calling getAdapter on an interface with no concrete binding; JDK types not covered by built-in adapters when reflection access is denied on the JPMS classpath.","commonSituations":"Java modules (JPMS) blocking reflective access to JDK types; classes lacking a no-arg constructor with no InstanceCreator registered; types entirely filtered by excludeFieldsWithModifiers or custom ExclusionStrategy; very old or custom Gson builds missing factories; registering only a TypeAdapterFactory that returns null for everything by mistake.","solutions":["Register a TypeAdapter or TypeAdapterFactory for the offending type via GsonBuilder.registerTypeAdapter / registerTypeAdapterFactory.","If the class lacks a no-arg constructor, register an InstanceCreator for it.","If using JPMS, open the relevant packages to Gson (add-opens JVM flags) or switch to a records-friendly setup.","Check reflection filters / excludeFieldsWithModifiers aren't excluding the type entirely."],"exampleFix":"// before: no adapter available, e.g. class without accessible constructor\nclass NoDefaultCtor { NoDefaultCtor(int x) {} }\nGson gson = new Gson();\nString json = gson.toJson(new NoDefaultCtor(1)); // may throw 'cannot handle'\n\n// after: register an InstanceCreator / adapter\nclass NoDefaultCtorIC implements InstanceCreator<NoDefaultCtor> {\n  public NoDefaultCtor createInstance(Type t) { return new NoDefaultCtor(0); }\n}\nGson gson = new GsonBuilder().registerTypeAdapter(NoDefaultCtor.class, new NoDefaultCtorIC()).create();","handlingStrategy":"validation","validationCode":"// Probe whether Gson can handle a type before using it\nstatic boolean isHandled(Gson gson, TypeToken<?> type) {\n  try {\n    return gson.getAdapter(type) != null;\n  } catch (IllegalArgumentException e) {\n    return false;\n  }\n}","typeGuard":"static <T> boolean hasAdapter(Gson gson, TypeToken<T> type) {\n  try { gson.getAdapter(type); return true; }\n  catch (IllegalArgumentException e) { return false; }\n}","tryCatchPattern":"try {\n  TypeAdapter<Foo> a = gson.getAdapter(TypeToken.get(Foo.class));\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"cannot handle\")) {\n    // register an InstanceCreator / TypeAdapter, or open packages for reflection\n  } else throw e;\n}","preventionTips":["Register TypeAdapter / InstanceCreator for types lacking a default constructor.","On JPMS, open the relevant packages to Gson with --add-opens.","Audit reflection filters and ExclusionStrategies so they don't fully exclude needed types.","Add smoke tests that build a TypeAdapter for every domain type you serialize."],"tags":["gson-core","type-adapter","reflection","no-adapter","configuration"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}