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

  1. Change the copied state to use supported types: widen Short/Byte to Integer, BigDecimal to Double or String.
  2. If you need rich object graphs, use Java serialization or an explicit mapping instead of ObjectCopier — it is deliberately value-only.
  3. Check the array branch too: only primitive-component arrays are supported (see the sibling 'Unsupported array' error).
  4. 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

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


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