google/gson · error · JsonParseException
null is not allowed as value for record component
Error message
null is not allowed as value for record component '${fieldName}' of primitive type; at path ${path} What it means
When deserializing JSON into a record with a primitive-typed component (int, long, boolean, etc.), Gson reads each value into a constructor argument array. A JSON null cannot be assigned to a primitive slot, so readIntoArray throws JsonParseException before the constructor is ever called.
Solutions
- Change the primitive record component to its boxed wrapper type (Integer, Long, Boolean) so null is accepted
- Pre-process the JSON to replace null values with sensible defaults before calling fromJson
- Register a custom TypeAdapter that substitutes a default value (e.g. 0) when the JSON value is null
Example fix
// before
record Person(int age) {}
gson.fromJson("{\"age\":null}", Person.class); // throws
// after
record Person(Integer age) {}
gson.fromJson("{\"age\":null}", Person.class); // age is null, no error Defensive patterns
Strategy: validation
Validate before calling
// Before deserializing, scan the JSON for nulls on primitive record components
public static void checkPrimitiveNulls(JsonElement json, Class<?> recordType) {
var components = recordType.getRecordComponents();
var obj = json.getAsJsonObject();
for (var c : components) {
if (c.getType().isPrimitive() && obj.has(c.getName())
&& obj.get(c.getName()).isJsonNull()) {
throw new IllegalStateException(
"JSON null for primitive record component: " + c.getName());
}
}
} Type guard
// Prefer boxed types for nullable components
record Person(Integer age) {} // Integer accepts null; int does not Try / catch
try {
Person p = gson.fromJson(json, Person.class);
} catch (JsonParseException e) {
if (e.getMessage().contains("null is not allowed")) {
// default the primitive or use a nullable wrapper
}
} Prevention
- Use boxed wrapper types (Integer, Long, Boolean) for record components that may be null in JSON
- Validate the JSON payload for nulls on primitive fields before calling fromJson
- Document which record components are nullable vs required
When it happens
Trigger: Deserializing JSON containing a null literal for a field mapped to a primitive record component, e.g. {"age": null} into record Person(int age).
Common situations: A backend API returns null for a field the client modeled as a primitive int/long/boolean in a record; schema evolution where a previously-non-null field becomes nullable.
Related errors
- Could not find the index in the constructor
- Failed to invoke constructor
- null is not a valid AtomicLongArray element
- Accessor threw exception
- Array must have size 1, but has size
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/40c0745276410d0d.
Report an issue: GitHub.
Appendix: source
Thrown at gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java:262
fieldValue = field.get(source);
}
@SuppressWarnings("ReferenceEquality")
boolean isSameObject = fieldValue == source;
if (isSameObject) {
// avoid direct recursion
return;
}
writer.name(serializedName);
writeTypeAdapter.write(writer, fieldValue);
}
@Override
void readIntoArray(JsonReader reader, int index, Object[] target)
throws IOException, JsonParseException {
Object fieldValue = typeAdapter.read(reader);
if (fieldValue == null && isPrimitive) {
throw new JsonParseException(
"null is not allowed as value for record component '"
+ fieldName
+ "' of primitive type; at path "
+ reader.getPath());
}
target[index] = fieldValue;
}
@Override
void readIntoField(JsonReader reader, Object target)
throws IOException, IllegalAccessException {
Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive) {
if (blockInaccessible) {
checkAccessible(target, field);
} else if (isStaticFinalField) {
// Reflection does not permit setting value of `static final` field, even after calling
// `setAccessible`View on GitHub (pinned to 310ac341f2)