{"record":{"id":"888e626d3c052ea3","repo":"oracle/graal","slug":"unexpected-value-instance","errorCode":null,"errorMessage":"Unexpected value: ${instance}","messagePattern":"Unexpected value: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/JsonReplayCodec.java","lineNumber":456,"sourceCode":"            return Number.class;\n        }\n\n        @Override\n        public String tag() {\n            return \"number\";\n        }\n\n        @Override\n        public void serialize(Object instance, JsonBuilder.ObjectBuilder objectBuilder, RecursiveSerializer serializer) throws IOException {\n            objectBuilder.append(\"class\", instance.getClass().getSimpleName());\n            String value = switch (instance) {\n                case Integer n -> Integer.toHexString(n);\n                case Byte n -> Integer.toHexString(n);\n                case Short n -> Integer.toHexString(n);\n                case Long n -> Long.toHexString(n);\n                case Float n -> floatToHex(n);\n                case Double n -> doubleToHex(n);\n                default -> throw new IllegalArgumentException(\"Unexpected value: \" + instance);\n            };\n            objectBuilder.append(\"value\", value);\n        }\n\n        @Override\n        public Object deserialize(EconomicMap<String, Object> json, RecursiveDeserializer deserializer, CompilationProxies.ProxyFactory proxyFactory) {\n            String className = (String) json.get(\"class\");\n            String value = (String) json.get(\"value\");\n            switch (className) {\n                case \"Integer\" -> {\n                    return Integer.parseUnsignedInt(value, HEX_RADIX);\n                }\n                case \"Byte\" -> {\n                    return (byte) Integer.parseUnsignedInt(value, HEX_RADIX);\n                }\n                case \"Short\" -> {\n                    return (short) Integer.parseUnsignedInt(value, HEX_RADIX);\n                }","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/JsonReplayCodec.java#L438-L474","documentation":"The primitive-constant serializer accepts only Integer, Byte, Short, Long, Float, and Double and encodes them as hex strings. Serialize() throws IllegalArgumentException('Unexpected value: ...') when it receives any other wrapper type — typically Boolean, Character, or a boxed value from a different serializer version.","triggerScenarios":"Calling the JSON replay serializer on a recorded constant that is a Boolean or Character (or Void/other boxed primitive) — the pattern match in the switch falls through to default.","commonSituations":"A recorded compiler-interface method takes a boolean or char parameter and no dedicated serializer covers it; GraalVM version drift that starts recording a previously unsupported parameter type; custom compiler-interface additions.","solutions":["Add Boolean/Character cases to the switch in JsonReplayCodec.java:456 (serialize 'true'/'false' or the char) and matching deserialize cases","Check the chained value in the message to confirm exactly which type leaked through, then trace which serializer should have claimed it","Update both halves of the codec (serialize AND deserialize) so the file stays round-trippable"],"exampleFix":"// before\nString value = switch (instance) {\n    case Integer n -> Integer.toHexString(n);\n    // ...\n    default -> throw new IllegalArgumentException(\"Unexpected value: \" + instance);\n};\n// after: add\n    case Boolean b -> Boolean.toString(b);\n    case Character c -> Integer.toHexString(c);\n// and the mirror cases in deserialize(...)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean isSupportedPrimitiveConstant(Object v) {\n    return v instanceof Integer || v instanceof Byte || v instanceof Short\n        || v instanceof Long || v instanceof Float || v instanceof Double;\n}","tryCatchPattern":null,"preventionTips":["When introducing a new parameter type into the recorded compiler interface, extend the constant serializer switch in the same change","Add a round-trip unit test (serialize then deserialize) for every supported primitive wrapper"],"tags":["graalvm","replay","serialization","boxing"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}