{"record":{"id":"c1eee046c03efd06","repo":"oracle/graal","slug":"unexpected-value-registerconfig","errorCode":null,"errorMessage":"Unexpected value: ${registerConfig}","messagePattern":"Unexpected value: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/JsonReplayCodec.java","lineNumber":1677,"sourceCode":"\n        @Override\n        public Class<?> clazz() {\n            return RegisterConfig.class;\n        }\n\n        @Override\n        public String tag() {\n            return \"registerConfig\";\n        }\n\n        @Override\n        public void serialize(Object instance, JsonBuilder.ObjectBuilder objectBuilder, RecursiveSerializer serializer) throws IOException {\n            RegisterConfig registerConfig = (RegisterConfig) instance;\n            String name = switch (registerConfig) {\n                case AMD64HotSpotRegisterConfig ignored -> \"AMD64\";\n                case RISCV64HotSpotRegisterConfig ignored -> \"RISCV64\";\n                case AArch64HotSpotRegisterConfig ignored -> \"AArch64\";\n                default -> throw new IllegalStateException(\"Unexpected value: \" + registerConfig);\n            };\n            objectBuilder.append(\"name\", name);\n            serializer.serialize(hostTarget, objectBuilder.append(\"target\"));\n            serializer.serialize(registerConfig.getAllocatableRegisters(), objectBuilder.append(\"allocatable\"));\n            objectBuilder.append(\"windowsOS\", isHostWindowsOS);\n        }\n\n        @Override\n        @SuppressWarnings(\"unchecked\")\n        public Object deserialize(EconomicMap<String, Object> json, RecursiveDeserializer deserializer, CompilationProxies.ProxyFactory proxyFactory) throws DeserializationException {\n            String name = (String) json.get(\"name\");\n            TargetDescription targetDescription = (TargetDescription) deserializer.deserialize(json.get(\"target\"), proxyFactory);\n            List<Register> allocatable = (List<Register>) deserializer.deserialize(json.get(\"allocatable\"), proxyFactory);\n            switch (name) {\n                case \"AMD64\" -> {\n                    boolean windowsOS = (boolean) json.get(\"windowsOS\");\n                    return new AMD64HotSpotRegisterConfig(targetDescription, allocatable, windowsOS);\n                }","sourceCodeStart":1659,"sourceCodeEnd":1695,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/JsonReplayCodec.java#L1659-L1695","documentation":"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: ...').","triggerScenarios":"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.","commonSituations":"Forked GraalVM with an extra architecture; version drift adding a new register-config class; wrapping configs in delegates for testing.","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"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean isSupportedRegisterConfig(RegisterConfig rc) {\n    return rc instanceof AMD64HotSpotRegisterConfig\n        || rc instanceof RISCV64HotSpotRegisterConfig\n        || rc instanceof AArch64HotSpotRegisterConfig;\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["graalvm","replay","serialization","register-config"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}