google/gson · error · IllegalStateException
Could not find the index in the constructor '${constructor}'
Error message
Could not find the index in the constructor '${constructor}' for field with name '${fieldName}', unable to determine which argument in the constructor the field corresponds to. This is unexpected behavior, as we expect the RecordComponents to have the same names as the fields in the Java class, and that the order of the RecordComponents is the same as the order of the canonical constructor parameters. What it means
While deserializing a record, Gson maps each field to a canonical constructor parameter by looking up the record component name. If a field name has no matching component, it cannot determine the constructor argument index and throws IllegalStateException. The message itself states this is unexpected because record component names should always match their fields.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java:631
zeroes.put(long.class, 0L);
zeroes.put(float.class, 0F);
zeroes.put(double.class, 0D);
zeroes.put(char.class, '\0');
zeroes.put(boolean.class, false);
return zeroes;
}
@Override
Object[] createAccumulator() {
return constructorArgsDefaults.clone();
}
@Override
void readField(Object[] accumulator, JsonReader in, BoundField field) throws IOException {
// Obtain the component index from the name of the field backing it
Integer componentIndex = componentIndices.get(field.fieldName);
if (componentIndex == null) {
throw new IllegalStateException(
"Could not find the index in the constructor '"
+ ReflectionHelper.constructorToString(constructor)
+ "' for field with name '"
+ field.fieldName
+ "', unable to determine which argument in the constructor the field corresponds"
+ " to. This is unexpected behavior, as we expect the RecordComponents to have the"
+ " same names as the fields in the Java class, and that the order of the"
+ " RecordComponents is the same as the order of the canonical constructor"
+ " parameters.");
}
field.readIntoArray(in, componentIndex, accumulator);
}
@Override
T finalize(Object[] accumulator) {
try {
return constructor.newInstance(accumulator);
} catch (IllegalAccessException e) {View on GitHub (pinned to 310ac341f2)
Solutions
- Add ProGuard/R8 keep rules to preserve record component names (-keepattributes Record)
- Register a custom TypeAdapter for the record to bypass Gson's reflective record handling
- If no bytecode manipulation is involved, report the issue to the Gson project with a reproducer
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify field names match record component names at startup
public static void validateRecordFields(Class<?> recordType) {
var componentNames = Arrays.stream(recordType.getRecordComponents())
.map(RecordComponent::getName).collect(Collectors.toSet());
for (Field f : recordType.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers()) && !componentNames.contains(f.getName())) {
throw new IllegalStateException("Field " + f.getName()
+ " has no matching record component in " + recordType);
}
}
} Try / catch
try {
MyRecord r = gson.fromJson(json, MyRecord.class);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Could not find the index")) {
// likely bytecode manipulation; use a custom TypeAdapter
}
} Prevention
- Add ProGuard/R8 keep rules (-keepattributes Record) to preserve record component names
- Register custom TypeAdapters for records when using obfuscation or bytecode manipulation
- Run an integration test that round-trips each record through Gson before shipping
When it happens
Trigger: Bytecode manipulation (obfuscation, instrumentation, code weaving) renames record fields differently from their RecordComponents; a non-standard JVM or unusual record implementation breaks the expected name correspondence.
Common situations: ProGuard/R8 obfuscation rules applied to records without keep rules; AOP or agent instrumentation altering field metadata; a Gson-internal inconsistency under exotic conditions.
Related errors
- Cannot allocate ${c}. Usage of JDK sun.misc.Unsafe is enable
- Accessor ${accessorDescription} threw exception
- null is not allowed as value for record component '${fieldNa
- Cannot set value of 'static final' ${fieldDescription}
- Failed to invoke constructor '${constructor}' with args ${ac
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/937dce0e14374347.
Report an issue: GitHub.