oracle/graal · error · IllegalArgumentException
Unsupported type: Value: %s, Value type: %s
Error message
Unsupported type: Value: %s, Value type: %s
What it means
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.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/util/ObjectCopierOutputStream.java:119
out.writeBoolean((Boolean) value);
} else if (valueClz == Byte.class) {
internalWriteByte((Byte) value);
} else if (valueClz == Short.class) {
out.writeShort((Short) value);
} else if (valueClz == Character.class) {
out.writeChar((Character) value);
} else if (valueClz == Integer.class) {
internalWritePackedSigned((int) value);
} else if (valueClz == Long.class) {
internalWritePackedSigned((long) value);
} else if (valueClz == Float.class) {
out.writeFloat((Float) value);
} else if (valueClz == Double.class) {
out.writeDouble((Double) value);
} else if (valueClz == String.class) {
writeStringValue((String) value);
} else {
throw new IllegalArgumentException(String.format("Unsupported type: Value: %s, Value type: %s", value, valueClz));
}
debugPrintValue(value);
}
protected void debugPrintValue(Object value) {
if (debugOut != null) {
Object debugValue = switch (value) {
case String s -> ObjectCopier.Encoder.escapeDebugStringValue(s);
case Character c -> (int) c;
default -> value;
};
debugOut.printf(" %s", debugValue);
}
}
public void writeStringValue(String value) throws IOException {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
internalWritePackedUnsignedInt(bytes.length);View on GitHub (pinned to a66e9ccd1d)
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.
Example fix
// before
state.put("port", Short.valueOf(port));
ObjectCopier.copy(state, out);
// after
state.put("port", (int) port); // Integer is supported
ObjectCopier.copy(state, out); Defensive patterns
Strategy: type-guard
Validate before calling
static boolean isCopierScalar(Object v) {
if (v == null) return true;
Class<?> c = v.getClass();
return c == Boolean.class || c == Character.class || c == Integer.class
|| c == Long.class || c == Float.class || c == Double.class || c == String.class;
}
// normalize before copying
static Object normalize(Object v) {
if (v instanceof Short s || v instanceof Byte b) return ((Number) v).intValue();
if (v instanceof java.math.BigDecimal bd) return bd.toPlainString();
return v;
} Type guard
static boolean isCopierScalar(Object v) {
if (v == null) return true;
Class<?> c = v.getClass();
return c == Boolean.class || c == Character.class || c == Integer.class
|| c == Long.class || c == Float.class || c == Double.class || c == String.class;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unsupported type: Value: %s, Value type: %s
- Unsupported array: Value: %s, Value type: %s
- Key: %s, Value: %s, Value type: %s
- undecoded bytes
- Cannot compare {JavaLangRuntimeVersion.__name__} to {type(ot
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/067a9f2718b794c7.
Report an issue: GitHub.