oracle/graal · error · IllegalStateException
Unexpected value: ${registerConfig}
Error message
Unexpected value: ${registerConfig} What it means
RegisterConfigSerializer.serialize maps a live RegisterConfig instance to a tag string by instanceof-pattern match over AMD64HotSpotRegisterConfig, RISCV64HotSpotRegisterConfig, and AArch64HotSpotRegisterConfig. Any other RegisterConfig implementation (custom subclass, new backend) hits IllegalStateException('Unexpected value: ...').
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/JsonReplayCodec.java:1677
@Override
public Class<?> clazz() {
return RegisterConfig.class;
}
@Override
public String tag() {
return "registerConfig";
}
@Override
public void serialize(Object instance, JsonBuilder.ObjectBuilder objectBuilder, RecursiveSerializer serializer) throws IOException {
RegisterConfig registerConfig = (RegisterConfig) instance;
String name = switch (registerConfig) {
case AMD64HotSpotRegisterConfig ignored -> "AMD64";
case RISCV64HotSpotRegisterConfig ignored -> "RISCV64";
case AArch64HotSpotRegisterConfig ignored -> "AArch64";
default -> throw new IllegalStateException("Unexpected value: " + registerConfig);
};
objectBuilder.append("name", name);
serializer.serialize(hostTarget, objectBuilder.append("target"));
serializer.serialize(registerConfig.getAllocatableRegisters(), objectBuilder.append("allocatable"));
objectBuilder.append("windowsOS", isHostWindowsOS);
}
@Override
@SuppressWarnings("unchecked")
public Object deserialize(EconomicMap<String, Object> json, RecursiveDeserializer deserializer, CompilationProxies.ProxyFactory proxyFactory) throws DeserializationException {
String name = (String) json.get("name");
TargetDescription targetDescription = (TargetDescription) deserializer.deserialize(json.get("target"), proxyFactory);
List<Register> allocatable = (List<Register>) deserializer.deserialize(json.get("allocatable"), proxyFactory);
switch (name) {
case "AMD64" -> {
boolean windowsOS = (boolean) json.get("windowsOS");
return new AMD64HotSpotRegisterConfig(targetDescription, allocatable, windowsOS);
}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Identify the actual class from the message and add a matching case + name to serialize() and a mirror case in deserialize()
- Avoid wrapping register configs in decorators when replay recording is enabled
- Record/replay on matching builds
Defensive patterns
Strategy: type-guard
Type guard
static boolean isSupportedRegisterConfig(RegisterConfig rc) {
return rc instanceof AMD64HotSpotRegisterConfig
|| rc instanceof RISCV64HotSpotRegisterConfig
|| rc instanceof AArch64HotSpotRegisterConfig;
} Prevention
- Do not wrap register configs in decorator classes when replay recording is enabled
- When porting a new backend, extend both register-config serializer switches (errors 151 and 152) in the same change
When it happens
Trigger: Serializing a replay on a JVM whose HotSpot register config is a class outside the three known ones — custom backend, a new port, or a config wrapper/decorator class introduced by a newer version.
Common situations: Forked GraalVM with an extra architecture; version drift adding a new register-config class; wrapping configs in delegates for testing.
Related errors
- Invalid replay string table index
- Invalid replay string definition index
- Invalid replay symbolic method index
- Invalid replay symbolic method definition index
- Invalid replay registration index
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/c1eee046c03efd06.
Report an issue: GitHub.