oracle/graal · error · DeserializationException
Invalid constant.
Error message
Invalid constant.
What it means
EnumSerializer.deserialize resolves an enum constant by name: it loads the enum class (from the 'holder' entry) and scans getEnumConstants() for one whose name() equals the recorded 'constant'. If no constant matches, it throws DeserializationException('Invalid constant.') — the enum exists but the name does not.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/JsonReplayCodec.java:572
@Override
public void serialize(Object instance, JsonBuilder.ObjectBuilder objectBuilder, RecursiveSerializer serializer) throws IOException {
Enum<?> en = (Enum<?>) instance;
serializer.serialize(en.getClass(), objectBuilder.append("holder"));
objectBuilder.append("constant", en.name());
}
@SuppressWarnings("unchecked")
@Override
public Object deserialize(EconomicMap<String, Object> json, RecursiveDeserializer deserializer, CompilationProxies.ProxyFactory proxyFactory) throws DeserializationException {
Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) deserializer.deserialize(json.get("holder"), proxyFactory);
String constantName = (String) json.get("constant");
for (Enum<?> constant : enumClass.getEnumConstants()) {
if (constant.name().equals(constantName)) {
return constant;
}
}
throw new DeserializationException(this, json, "Invalid constant.");
}
}
private static final class ArraySerializer implements ObjectSerializer {
private final CompilerInterfaceDeclarations declarations;
private ArraySerializer(CompilerInterfaceDeclarations declarations) {
this.declarations = declarations;
}
@Override
public boolean serializesSubclasses() {
return true;
}
@Override
public Class<?> clazz() {View on GitHub (pinned to a66e9ccd1d)
Solutions
- Use identical GraalVM builds for record and replay
- Inspect the entry's 'holder' and 'constant' fields (included in the DeserializationException context) and map the old name to the new one
- If replaying across versions is required, add a name-alias mapping in EnumSerializer before throwing
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the constant name against the enum before full replay
Class<? extends Enum<?>> ec = loadEnumClass(holderName);
boolean ok = Arrays.stream(ec.getEnumConstants()).anyMatch(c -> c.name().equals(constantName));
if (!ok) throw new IllegalArgumentException("Enum " + holderName + " has no constant " + constantName); Prevention
- Match GraalVM versions between record and replay so enum constants align
- If cross-version replay is required, maintain an alias table mapping removed/renamed enum constants
When it happens
Trigger: Deserializing an enum entry where 'constant' names a value absent from the loaded enum class: enum constant renamed/removed between the recording and replaying GraalVM builds, or a typo in hand-edited JSON.
Common situations: Version skew where CPUFeature or phase enums gained/renamed constants; replaying across CPU generations where a CPUFeature enum differs; manual JSON edits.
Related errors
- Unknown enum constant for
- No singleton found for ${registration}
- Unknown class ${className} for constant${value}
- Invalid marker type.
- Unexpected value: ${name}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/06de9066fad845c9.
Report an issue: GitHub.