oracle/graal · error · IllegalArgumentException

Expected an array constant for src, got {}

Error message

Expected an array constant for src, got {}

What it means

Thrown by HostVMAccess.copyArray when the src constant cannot be unwrapped to a live host array object: asObject(Object.class, src) returned null or the object's class is not an array. It guards the source side of the System.arraycopy delegation.

Source

Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:332

        Object copy = switch (source) {
            case boolean[] array -> array.clone();
            case byte[] array -> array.clone();
            case short[] array -> array.clone();
            case char[] array -> array.clone();
            case int[] array -> array.clone();
            case long[] array -> array.clone();
            case float[] array -> array.clone();
            case double[] array -> array.clone();
            default -> throw new IllegalArgumentException("Expected a primitive array constant, got " + primitiveArray);
        };
        return providers.getSnippetReflection().forObject(copy);
    }

    @Override
    public void copyArray(JavaConstant src, int srcPos, JavaConstant dest, int destPos, int length) {
        Object srcArray = providers.getSnippetReflection().asObject(Object.class, src);
        if (srcArray == null || !srcArray.getClass().isArray()) {
            throw new IllegalArgumentException("Expected an array constant for src, got " + src);
        }
        Object destArray = providers.getSnippetReflection().asObject(Object.class, dest);
        if (destArray == null || !destArray.getClass().isArray()) {
            throw new IllegalArgumentException("Expected an array constant for dest, got " + dest);
        }
        System.arraycopy(srcArray, srcPos, destArray, destPos, length);
    }

    private void doWriteArrayElement(Object array, ResolvedJavaType componentType, int index, JavaConstant element) {
        Object unwrappedValue;
        if (componentType.isPrimitive()) {
            if (componentType.getJavaKind() != element.getJavaKind()) {
                throw new IllegalArgumentException("Element " + element + " should be a " + componentType.getJavaKind() + ", got " + element.getJavaKind());
            }
            unwrappedValue = element.asBoxedPrimitive();
        } else {
            if (!element.getJavaKind().isObject()) {
                throw new IllegalArgumentException("Element " + element + " should be an object, got " + componentType);

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Check src wraps a real array before calling: unwrap and verify getClass().isArray() (or type it via metaAccess and check isArray())
  2. Ensure src was produced by forObject/asArrayConstant in the same provider context
  3. Fix argument order — src, srcPos, dest, destPos, length

Example fix

// before
hostVM.copyArray(elementConstant, 0, destConstant, 0, n);  // scalar src -> throws

// after
Object srcObj = snippetReflection.asObject(Object.class, srcConstant);
if (srcObj != null && srcObj.getClass().isArray()) {
    hostVM.copyArray(srcConstant, 0, destConstant, 0, n);
}
Defensive patterns

Strategy: type-guard

Validate before calling

Object s = snippetReflection.asObject(Object.class, src);
if (s == null || !s.getClass().isArray()) {
    throw new IllegalArgumentException("src is not a live array: " + src);

Type guard

static boolean isLiveArrayConstant(JavaConstant c, SnippetReflectionProvider sp) {
    Object o = sp.asObject(Object.class, c);
    return o != null && o.getClass().isArray();
}

Try / catch

catch (IllegalArgumentException e) { materialize src via asArrayConstant and retry once }

Prevention

When it happens

Trigger: Calling copyArray(src, srcPos, dest, destPos, length) where src is a non-array constant (a scalar/object constant), a null-valued constant (asObject yields null), or a constant not backed by a host object in the current snippet reflection context.

Common situations: Generic buffer-copy helpers invoked with mixed constant kinds; constants from serialized compilation data lacking object backing; wrong argument order (passing an element or dest where src is expected).

Related errors


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