{"record":{"id":"cd4d2082d3f78537","repo":"google/gson","slug":"accessor-accessordescription-threw-exception","errorCode":null,"errorMessage":"Accessor ${accessorDescription} threw exception","messagePattern":"Accessor (.+?) threw exception","errorType":"exception","errorClass":"JsonIOException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java","lineNumber":240,"sourceCode":"      void write(JsonWriter writer, Object source) throws IOException, IllegalAccessException {\n        if (blockInaccessible) {\n          if (accessor == null) {\n            checkAccessible(source, field);\n          } else {\n            // Note: This check might actually be redundant because access check for canonical\n            // constructor should have failed already\n            checkAccessible(source, accessor);\n          }\n        }\n\n        Object fieldValue;\n        if (accessor != null) {\n          try {\n            fieldValue = accessor.invoke(source);\n          } catch (InvocationTargetException e) {\n            String accessorDescription =\n                ReflectionHelper.getAccessibleObjectDescription(accessor, false);\n            throw new JsonIOException(\n                \"Accessor \" + accessorDescription + \" threw exception\", e.getCause());\n          }\n        } else {\n          fieldValue = field.get(source);\n        }\n\n        @SuppressWarnings(\"ReferenceEquality\")\n        boolean isSameObject = fieldValue == source;\n        if (isSameObject) {\n          // avoid direct recursion\n          return;\n        }\n        writer.name(serializedName);\n        writeTypeAdapter.write(writer, fieldValue);\n      }\n\n      @Override\n      void readIntoArray(JsonReader reader, int index, Object[] target)","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java#L222-L258","documentation":"When serializing a Java record, Gson reads each component value by invoking its accessor method via reflection (accessor.invoke(source)). If the accessor throws, Gson catches the InvocationTargetException and rethrows a JsonIOException wrapping the original cause. This is a failure inside your record's own accessor logic, not a Gson configuration issue.","triggerScenarios":"Calling gson.toJson(recordInstance) where the record overrides an accessor method (or the implicit accessor dereferences a null component) and that method throws a NullPointerException, IllegalStateException, or any other runtime exception.","commonSituations":"A record accessor that performs validation or lazy computation fails on bad state; a record component is null and the accessor calls a method on it; migrating a class with getter logic to a record where the accessor now throws.","solutions":["Inspect the caused-by exception (e.getCause()) to identify which accessor threw and why","Fix the bug in the record accessor or the data it depends on","Register a custom JsonSerializer<T> for the record type to bypass the accessor entirely during serialization"],"exampleFix":"// before\nrecord User(String name) {\n    @Override public String name() { return name.toUpperCase(); } // NPE if name is null\n}\ngson.toJson(new User(null)); // throws\n\n// after\nrecord User(String name) {\n    @Override public String name() { return name == null ? null : name.toUpperCase(); }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    String json = gson.toJson(recordInstance);\n} catch (JsonIOException e) {\n    // e.getCause() holds the accessor's original exception\n    Throwable cause = e.getCause();\n    log.error(\"Record accessor failed during serialization: {}\", cause.getMessage(), cause);\n    // fall back to a custom serializer or omit the field\n}","preventionTips":["Ensure record accessor methods (including overrides) never throw for null components","Guard accessor logic with null checks before dereferencing","Register a custom JsonSerializer for records whose accessors have complex logic"],"tags":["serialization","record","reflection"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}