{"record":{"id":"067a9f2718b794c7","repo":"oracle/graal","slug":"unsupported-type-value-s-value-type-s-067a9f","errorCode":null,"errorMessage":"Unsupported type: Value: %s, Value type: %s","messagePattern":"Unsupported type: Value: (.+?), Value type: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/util/ObjectCopierOutputStream.java","lineNumber":119,"sourceCode":"            out.writeBoolean((Boolean) value);\n        } else if (valueClz == Byte.class) {\n            internalWriteByte((Byte) value);\n        } else if (valueClz == Short.class) {\n            out.writeShort((Short) value);\n        } else if (valueClz == Character.class) {\n            out.writeChar((Character) value);\n        } else if (valueClz == Integer.class) {\n            internalWritePackedSigned((int) value);\n        } else if (valueClz == Long.class) {\n            internalWritePackedSigned((long) value);\n        } else if (valueClz == Float.class) {\n            out.writeFloat((Float) value);\n        } else if (valueClz == Double.class) {\n            out.writeDouble((Double) value);\n        } else if (valueClz == String.class) {\n            writeStringValue((String) value);\n        } else {\n            throw new IllegalArgumentException(String.format(\"Unsupported type: Value: %s, Value type: %s\", value, valueClz));\n        }\n        debugPrintValue(value);\n    }\n\n    protected void debugPrintValue(Object value) {\n        if (debugOut != null) {\n            Object debugValue = switch (value) {\n                case String s -> ObjectCopier.Encoder.escapeDebugStringValue(s);\n                case Character c -> (int) c;\n                default -> value;\n            };\n            debugOut.printf(\" %s\", debugValue);\n        }\n    }\n\n    public void writeStringValue(String value) throws IOException {\n        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);\n        internalWritePackedUnsignedInt(bytes.length);","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/util/ObjectCopierOutputStream.java#L101-L137","documentation":"IllegalArgumentException from ObjectCopierOutputStream's scalar-writing method: the value's class is not one of the supported primitives/String cases (Boolean, Character, Integer, Long, Float, Double, String). ObjectCopier is a small value-only copier used to snapshot simple values (not a general Java serialization mechanism), so any other scalar type is rejected with the value and class in the message.","triggerScenarios":"Calling the copier's write path (typically ObjectCopier.copy or the stream's writeValue) with a scalar outside the whitelist — Short, Byte, BigDecimal, AtomicBoolean, or an arbitrary object that did not take the array branch.","commonSituations":"Trying to snapshot state that contains boxed Short/Byte produced by NIO or protocol parsers; assuming ObjectCopier behaves like Java serialization for arbitrary Serializable objects; adding a new field to copied state without checking the supported set.","solutions":["Change the copied state to use supported types: widen Short/Byte to Integer, BigDecimal to Double or String.","If you need rich object graphs, use Java serialization or an explicit mapping instead of ObjectCopier — it is deliberately value-only.","Check the array branch too: only primitive-component arrays are supported (see the sibling 'Unsupported array' error).","Write a round-trip test for every type you copy to catch unsupported types early."],"exampleFix":"// before\nstate.put(\"port\", Short.valueOf(port));\nObjectCopier.copy(state, out);\n\n// after\nstate.put(\"port\", (int) port); // Integer is supported\nObjectCopier.copy(state, out);","handlingStrategy":"type-guard","validationCode":"static boolean isCopierScalar(Object v) {\n    if (v == null) return true;\n    Class<?> c = v.getClass();\n    return c == Boolean.class || c == Character.class || c == Integer.class\n        || c == Long.class || c == Float.class || c == Double.class || c == String.class;\n}\n\n// normalize before copying\nstatic Object normalize(Object v) {\n    if (v instanceof Short s || v instanceof Byte b) return ((Number) v).intValue();\n    if (v instanceof java.math.BigDecimal bd) return bd.toPlainString();\n    return v;\n}","typeGuard":"static boolean isCopierScalar(Object v) {\n    if (v == null) return true;\n    Class<?> c = v.getClass();\n    return c == Boolean.class || c == Character.class || c == Integer.class\n        || c == Long.class || c == Float.class || c == Double.class || c == String.class;\n}","tryCatchPattern":null,"preventionTips":["Keep copied state to primitives and String by design; document the whitelist at the state class.","Do not assume ObjectCopier handles Serializable — it is a value-only copier.","Add a copy round-trip test for every new state field."],"tags":["serialization","object-copier","type-whitelist","illegal-argument"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}