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

  1. 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()).
  2. If the type must be first-class, add a new tag branch to writeTypedValue and the matching readTypedValue branch, keeping tags stable.
  3. For Short values, widen to Integer explicitly to avoid surprises on the read side.
  4. 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

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


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/7ae0d42d87014d70. Report an issue: GitHub.