oracle/graal · error · IllegalArgumentException
Expected an EspressoExternalObjectConstant, got {}
Error message
Expected an EspressoExternalObjectConstant, got {} What it means
clonePrimitiveArray(primitiveArray) deep-copies a guest primitive array by unwrapping an EspressoExternalObjectConstant and calling the guest helper clonePrimitiveArray. A constant from any other JVMCI backend has no guest Value to clone, so it is rejected with IllegalArgumentException before the helper is invoked.
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java:593
return new EspressoExternalObjectConstant(this, array);
}
@Override
public JavaConstant createPrimitiveArray(JavaKind kind, int length) {
if (kind == null || !kind.isPrimitive() || kind == JavaKind.Void) {
throw new IllegalArgumentException("Expected a non-void primitive kind, got " + kind);
}
if (length < 0) {
throw new NegativeArraySizeException("Negative array size: " + length);
}
Value array = invokeJVMCIHelper("newPrimitiveArray", (int) kind.getTypeChar(), 1, length);
return new EspressoExternalObjectConstant(this, array);
}
@Override
public JavaConstant clonePrimitiveArray(JavaConstant primitiveArray) {
if (!(primitiveArray instanceof EspressoExternalObjectConstant objectConstant)) {
throw new IllegalArgumentException("Expected an EspressoExternalObjectConstant, got " + safeGetClass(primitiveArray));
}
EspressoResolvedObjectType arrayType = objectConstant.getType();
if (!(arrayType.isArray() && arrayType.getComponentType().isPrimitive())) {
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()) {View on GitHub (pinned to a66e9ccd1d)
Solutions
- Only clone arrays originally created by this Espresso provider (createPrimitiveArray / asArrayConstant results).
- Guard with primitiveArray instanceof EspressoExternalObjectConstant and use host-side clone() for host arrays.
- Keep constants tagged with their originating provider in caches to avoid cross-provider leakage.
Example fix
// before
JavaConstant copy = vmAccess.clonePrimitiveArray(maybeHostConstant);
// after
JavaConstant copy = (maybeHostConstant instanceof EspressoExternalObjectConstant)
? vmAccess.clonePrimitiveArray(maybeHostConstant)
: hostCopy(maybeHostConstant); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(primitiveArray instanceof EspressoExternalObjectConstant)) {
// host array: clone on the host instead
} Type guard
static boolean isEspressoConstant(JavaConstant c) {
return c instanceof EspressoExternalObjectConstant;
} Try / catch
catch (IllegalArgumentException e) with 'Expected an EspressoExternalObjectConstant' -> clone host arrays with .clone(), guest arrays via the provider.
Prevention
- Snapshot helpers should branch on constant origin before cloning.
- Invalidate constant caches when a context is disposed.
- Tag constants with their provider in wrappers you control.
When it happens
Trigger: Passing a host-created array constant (JavaConstant.forObject(byte[]) or HotSpot constant) or a constant from another Espresso context to clonePrimitiveArray.
Common situations: Copy-on-write snapshot logic that sometimes receives host arrays; caching constants across provider lifecycles; tests with hand-built constants.
Related errors
- Invalid component type
- Element {} should be an espresso object constant, got {}
- Expected an EspressoExternalObjectConstant for src, got {}
- Expected an EspressoExternalObjectConstant for dest, got
- Expected an EspressoExternalObjectConstant, got
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/bb3fae899234c9bc.
Report an issue: GitHub.