{"record":{"id":"261b67ef92d8e660","repo":"google/gson","slug":"reflectionaccessfilter-does-not-permit-using-refle","errorCode":null,"errorMessage":"ReflectionAccessFilter does not permit using reflection for ${raw}. Register a TypeAdapter for this type or adjust the access filter.","messagePattern":"ReflectionAccessFilter does not permit using reflection for (.+?)\\. Register a TypeAdapter for this type or adjust the access filter\\.","errorType":"exception","errorClass":"JsonIOException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java","lineNumber":145,"sourceCode":"          return null;\n        }\n\n        @Override\n        public void write(JsonWriter out, T value) throws IOException {\n          out.nullValue();\n        }\n\n        @Override\n        public String toString() {\n          return \"AnonymousOrNonStaticLocalClassAdapter\";\n        }\n      };\n    }\n\n    FilterResult filterResult =\n        ReflectionAccessFilterHelper.getFilterResult(reflectionFilters, raw);\n    if (filterResult == FilterResult.BLOCK_ALL) {\n      throw new JsonIOException(\n          \"ReflectionAccessFilter does not permit using reflection for \"\n              + raw\n              + \". Register a TypeAdapter for this type or adjust the access filter.\");\n    }\n    boolean blockInaccessible = filterResult == FilterResult.BLOCK_INACCESSIBLE;\n\n    // If the type is actually a Java Record, we need to use the RecordAdapter instead. This will\n    // always be false on JVMs that do not support records.\n    if (ReflectionHelper.isRecord(raw)) {\n      @SuppressWarnings(\"unchecked\")\n      TypeAdapter<T> adapter =\n          (TypeAdapter<T>)\n              new RecordAdapter<>(\n                  raw, getBoundFields(gson, type, raw, blockInaccessible, true), blockInaccessible);\n      return adapter;\n    }\n\n    ObjectConstructor<T> constructor = constructorConstructor.get(type, true);","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java#L127-L163","documentation":"Gson's ReflectiveTypeAdapterFactory uses reflection to serialize/deserialize POJOs. When a registered ReflectionAccessFilter returns FilterResult.BLOCK_ALL for a type (or for a supertype encountered while scanning inherited fields), Gson refuses to use reflection and throws JsonIOException directing you to register a TypeAdapter or adjust the filter. This is a security-hardening feature to prevent reflection on sensitive or restricted types.","triggerScenarios":"Registering a ReflectionAccessFilter that blocks a type, then serializing/deserializing an instance of that type without a custom adapter; blocking platform/JDK or third-party library types; JPMS/restricted environments where reflection must be denied by policy.","commonSituations":"Security hardening that blocks reflection on internal/platform classes; blocking types from untrusted libraries; a global filter that is too broad and catches application types.","solutions":["Register a custom TypeAdapter for the blocked type via GsonBuilder.registerTypeAdapter(TypeToken, adapter)","Adjust the ReflectionAccessFilter to return ALLOW or BLOCK_INACCESSIBLE for that specific type instead of BLOCK_ALL","Exclude the field, or use a different (non-blocked) type for the data"],"exampleFix":"// before - filter blocks MyType, toJson throws\ngson.toJson(myTypeInstance);\n\n// after - register a TypeAdapter so reflection is not needed\nGson gson = new GsonBuilder()\n    .addReflectionAccessFilter(new ReflectionAccessFilter() {\n        @Override public FilterResult check(Class<?> raw) {\n            return raw == MyType.class ? FilterResult.ALLOW : FilterResult.BLOCK_ALL;\n        }\n    })\n    .registerTypeAdapter(MyType.class, myTypeAdapter)\n    .create();","handlingStrategy":"type-guard","validationCode":"// Pre-check whether reflection is blocked for a type before serializing\njava.util.List<ReflectionAccessFilter> filters = configuredFilters;\nFilterResult r = com.google.gson.internal.ReflectionAccessFilterHelper.getFilterResult(filters, MyType.class);\nif (r == FilterResult.BLOCK_ALL && !hasCustomAdapter(MyType.class)) {\n    throw new IllegalStateException(\"No adapter and reflection blocked for \" + MyType.class);\n}","typeGuard":"// Confirm a TypeAdapter is registered before relying on reflection\nstatic boolean hasAdapter(Gson gson, Class<?> type) {\n    return gson.getAdapter(TypeToken.get(type)).getClass().getName().contains(\"ReflectiveTypeAdapter\") == false;\n}","tryCatchPattern":"try {\n  String json = gson.toJson(obj);\n} catch (com.google.gson.JsonIOException e) {\n  // 'ReflectionAccessFilter does not permit...': register a TypeAdapter or allow the type\n}","preventionTips":["Always pair a blocking ReflectionAccessFilter with a registered TypeAdapter for affected types","Scope filters narrowly (per type) rather than blocking broadly","Document which types are blocked so callers know to supply adapters"],"tags":["json","reflection","security","access-filter","serialization"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}