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
- Validate dest's type with isArray() before the call.
- Allocate the destination via createPrimitiveArray or asArrayConstant.
- 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
- Double-check src/dest argument order at every copyArray call.
- Allocate destinations explicitly before copying.
- Beware placeholder constants in lazily-allocated buffers.
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
- Expected a non-void primitive kind, got {}
- Expected an array constant for src, got
- Expected an array type, got
- Invalid component type
- Element {} should be a {} but was {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/c4ab45be89233f4a.
Report an issue: GitHub.