oracle/graal · error · IllegalArgumentException

Expected an array constant for dest, got

Error message

Expected an array constant for dest, got 

What it means

copyArray's final guard requires the destination constant's guest type to be an array type before dispatching to the guest System.arraycopy. Passing a non-array Espresso constant as dest throws IllegalArgumentException('Expected an array constant for dest, ...') with the type that was found, preventing a doomed cross-language call.

Source

Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java:615

            throw new IllegalArgumentException("Expected a primitive array constant, got " + arrayType);
        }
        Value copy = invokeJVMCIHelper("clonePrimitiveArray", objectConstant.getValue());
        return new EspressoExternalObjectConstant(this, copy);
    }

    @Override
    public void copyArray(JavaConstant src, int srcPos, JavaConstant dest, int destPos, int length) {
        if (!(src instanceof EspressoExternalObjectConstant srcArray)) {
            throw new IllegalArgumentException("Expected an EspressoExternalObjectConstant for src, got " + safeGetClass(src));
        }
        if (!(dest instanceof EspressoExternalObjectConstant destArray)) {
            throw new IllegalArgumentException("Expected an EspressoExternalObjectConstant for dest, got " + safeGetClass(dest));
        }
        if (!srcArray.getType().isArray()) {
            throw new IllegalArgumentException("Expected an array constant for src, got " + srcArray.getType());
        }
        if (!destArray.getType().isArray()) {
            throw new IllegalArgumentException("Expected an array constant for dest, got " + destArray.getType());
        }
        try {
            invoke(java_lang_System_arraycopy, null, srcArray, JavaConstant.forInt(srcPos), destArray, JavaConstant.forInt(destPos), JavaConstant.forInt(length));
        } catch (InvocationException e) {
            if (e.getCause() instanceof PolyglotException polyglotException) {
                throw throwHostException(polyglotException);
            }
            throw e;
        }
    }

    @Override
    public void writeArrayElement(JavaConstant array, int index, JavaConstant element) {
        if (!(array instanceof EspressoExternalObjectConstant espressoArray)) {
            throw new IllegalArgumentException("Expected an EspressoExternalObjectConstant, got " + safeGetClass(array));
        }
        EspressoResolvedObjectType arrayType = espressoArray.getType();
        if (!arrayType.isArray()) {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Validate dest's type with isArray() before the call.
  2. Allocate the destination via createPrimitiveArray or asArrayConstant.
  3. Double-check src/dest argument order — a swapped scalar argument typically trips this guard.

Example fix

// before
vmAccess.copyArray(src, 0, someObjectConstant, 0, n); // swapped/wrong dest

// after
JavaConstant dest = vmAccess.createPrimitiveArray(JavaKind.Byte, n);
vmAccess.copyArray(src, 0, dest, 0, n);
Defensive patterns

Strategy: validation

Validate before calling

if (dest instanceof EspressoExternalObjectConstant e && !e.getType().isArray()) {
    dest = vmAccess.createPrimitiveArray(kind, neededLength);
}

Type guard

static boolean isGuestArray(JavaConstant c) {
    return c instanceof EspressoExternalObjectConstant e && e.getType().isArray();
}

Prevention

When it happens

Trigger: Using an Espresso object constant that is not an array (a single object, string, or mirror) as the copy destination.

Common situations: Destination variable shadowed or reassigned to a scalar; builder code that allocates the destination lazily and passes a placeholder; copy-paste of call sites with swapped src/dest.

Related errors


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