{"record":{"id":"8daba4249f09f47f","repo":"google/gson","slug":"gson-cannot-serialize-or-deserialize-type","errorCode":null,"errorMessage":"GSON cannot serialize or deserialize ${type}","messagePattern":"GSON cannot serialize or deserialize (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/Gson.java","lineNumber":498,"sourceCode":"    boolean skipPastFound = false;\n    for (TypeAdapterFactory factory : factories) {\n      if (!skipPastFound) {\n        @SuppressWarnings(\"ReferenceEquality\")\n        boolean isSkipPast = factory == skipPast;\n        if (isSkipPast) {\n          skipPastFound = true;\n        }\n        continue;\n      }\n\n      TypeAdapter<T> candidate = factory.create(this, type);\n      if (candidate != null) {\n        return candidate;\n      }\n    }\n\n    if (skipPastFound) {\n      throw new IllegalArgumentException(\"GSON cannot serialize or deserialize \" + type);\n    } else {\n      // Probably a factory from @JsonAdapter on a field\n      return getAdapter(type);\n    }\n  }\n\n  /**\n   * This method serializes the specified object into its equivalent representation as a tree of\n   * {@link JsonElement}s. This method should be used when the specified object is not a generic\n   * type. This method uses {@link Class#getClass()} to get the type for the specified object, but\n   * the {@code getClass()} loses the generic type information because of the Type Erasure feature\n   * of Java. Note that this method works fine if any of the object fields are of generic type, just\n   * the object itself should not be of a generic type. If the object is of generic type, use {@link\n   * #toJsonTree(Object, Type)} instead.\n   *\n   * @param src the object for which JSON representation is to be created\n   * @return JSON representation of {@code src}.\n   * @since 1.4","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/Gson.java#L480-L516","documentation":"Thrown by Gson.getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken) when, after skipping past the specified factory, no subsequent factory produces an adapter for the type. This is the path used by custom factories that delegate to the 'next' adapter; if there is no next adapter the type cannot be (de)serialized and an IllegalArgumentException is raised.","triggerScenarios":"A custom factory calling gson.getDelegateAdapter(this, type) when it is the last factory in the chain; delegating past a factory for a type only that factory handled; skipPast factory not actually registered (falls back to getAdapter, so this specific throw needs skipPastFound && no later match).","commonSituations":"Ordering mistake: a delegating factory registered after all relevant built-ins; a decorator factory that should wrap the default adapter but is placed last; manually iterating factories and skipping too far.","solutions":["Register the delegating TypeAdapterFactory BEFORE the built-in/fallback factory it wants to delegate to (use registerTypeAdapterFactory early).","Make sure there is a factory after skipPast able to handle the type.","If you do not actually need delegation, call getAdapter(type) instead of getDelegateAdapter(this, type).","Restructure so the decorator returns a non-null adapter itself rather than relying on a later factory."],"exampleFix":"// before: decorator registered last -> no delegate\nnew GsonBuilder()\n  .registerTypeAdapter(Foo.class, defaultFooAdapter)\n  .registerTypeAdapterFactory(decoratorThatDelegates) // last -> throws\n  .create();\n\n// after: decorator first so delegate exists after it\nnew GsonBuilder()\n  .registerTypeAdapterFactory(decoratorThatDelegates)\n  .registerTypeAdapter(Foo.class, defaultFooAdapter)\n  .create();","handlingStrategy":"validation","validationCode":"// Ensure the delegating factory is registered before fallbacks\n// Order matters: register decorator FIRST, then the adapter it delegates to.\nnew GsonBuilder()\n  .registerTypeAdapterFactory(decorator)   // earlier\n  .registerTypeAdapter(Foo.class, fallback) // later -> delegate exists\n  .create();","typeGuard":null,"tryCatchPattern":"try { gson.getDelegateAdapter(this, type); }\ncatch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"cannot serialize or deserialize\")) {\n    // fall back to getAdapter(type) or restructure factory order\n  } else throw e;\n}","preventionTips":["Register decorating factories before the adapters they wrap.","Prefer getAdapter(type) when delegation is not required.","Verify factory ordering in a unit test."],"tags":["gson-core","type-adapter","delegate","factory-ordering"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}