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 TypedDataOutputStream.writeTypedValue: the value's class is not one of the supported cases (Boolean, Character, Integer, Long, Float, Double, String, enum, byte[] as implied by the type-tag scheme — 'F','D','U', etc.). The stream is a minimal, versioned serialization format for option/config values, so anything outside the whitelist is rejected at write time with the value and its class in the message.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/util/TypedDataOutputStream.java:100
this.writeByte('I');
this.writeInt((Integer) value);
} else if (valueClz == Long.class) {
this.writeByte('J');
this.writeLong((Long) value);
} else if (valueClz == Float.class) {
this.writeByte('F');
this.writeFloat((Float) value);
} else if (valueClz == Double.class) {
this.writeByte('D');
this.writeDouble((Double) value);
} else if (valueClz == String.class) {
this.writeByte('U');
this.writeStringValue((String) value);
} else if (valueClz.isEnum()) {
this.writeByte('U');
this.writeStringValue(((Enum<?>) value).name());
} else {
throw new IllegalArgumentException(String.format("Unsupported type: Value: %s, Value type: %s", value, valueClz));
}
}
protected void writeStringValue(String value) throws IOException {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
this.writeInt(bytes.length);
this.write(bytes);
}
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Convert the value to a supported type before writing: String, Integer, Long, Float, Double, Boolean, Character, byte[], or a Java enum (enums are stored by name()).
- If the type must be first-class, add a new tag branch to writeTypedValue and the matching readTypedValue branch, keeping tags stable.
- For Short values, widen to Integer explicitly to avoid surprises on the read side.
- Add a unit test that round-trips every value type you intend to store.
Example fix
// before out.writeTypedValue(Short.valueOf((short) 3)); // throws // after out.writeTypedValue(3); // store as Integer
Defensive patterns
Strategy: type-guard
Validate before calling
static Object toTypedStreamValue(Object v) {
if (v instanceof Short s) return (int) s; // widen
if (v instanceof Byte b) return (int) b;
if (v instanceof Number n && !(v instanceof Integer || v instanceof Long
|| v instanceof Float || v instanceof Double)) return n.toString();
if (v != null && !(v instanceof Boolean || v instanceof Character || v instanceof String
|| v instanceof byte[] || v.getClass().isEnum()
|| v instanceof Integer || v instanceof Long || v instanceof Float || v instanceof Double)) {
return String.valueOf(v);
}
return v;
} Type guard
static boolean isSupportedTypedValue(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 || c.isEnum();
} Try / catch
try {
out.writeTypedValue(v);
} catch (IllegalArgumentException e) {
throw new ConfigException("unsupported option value type: " + e.getMessage(), e);
} Prevention
- Canonicalize all option values to the supported set at the point they enter the map.
- Never add a new option value type without extending both writeTypedValue and readTypedValue symmetrically.
- Unit-test the full value-type whitelist on every codec change.
When it happens
Trigger: Calling writeTypedValue(value) (directly or via OptionsEncoder.encode) with e.g. Short, BigDecimal, java.net.URL, List, or a non-enum POJO — valueClz matches none of the if-chains and falls through to the throw.
Common situations: Extending an option map with a new value type without extending the codec; passing boxed Short or BigDecimal values that silently worked with other serializers (DataOutputStream) but not this one; enums are fine but records/classes named like enums are not.
Related errors
- Key: %s, Value: %s, Value type: %s
- undecoded bytes
- Unsupported type: Value: %s, Value type: %s
- SpectrePHTBarriers can be set to 'AllTargets' if and only if
- register %s is not allocatable
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/7ae0d42d87014d70.
Report an issue: GitHub.