oracle/graal · error · IllegalArgumentException
Bad argument kind at index {}: expected Object, got {} wrapp
Error message
Bad argument kind at index {}: expected Object, got {} wrapped in a {} What it means
Thrown by the argument marshalling switch in EspressoExternalResolvedJavaMethod.invoke when a parameter is declared Object (reference type) and the argument is neither null nor an EspressoExternalObjectConstant. Null yields Java null for the guest call; non-null reference arguments must carry a guest polyglot Value, which only EspressoExternalObjectConstant provides. The message reports both the constant's JavaKind and its concrete class, distinguishing 'wrong kind' (e.g. an Int passed for a String parameter) from 'wrong provenance' (a foreign object constant).
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaMethod.java:368
case Float -> switch (argumentKind) {
case Long, Int, Char, Short, Byte -> (float) argument.asLong();
case Float -> argument.asFloat();
default ->
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Float, got " + argumentKind);
};
case Double -> switch (argumentKind) {
case Long, Int, Char, Short, Byte -> (double) argument.asLong();
case Float -> (double) argument.asFloat();
case Double -> argument.asDouble();
default ->
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Double, got " + argumentKind);
};
case Object -> {
if (argument.isNull()) {
yield null;
}
if (!(argument instanceof EspressoExternalObjectConstant objectConstant)) {
throw new IllegalArgumentException(
"Bad argument kind at index " + i + ": expected Object, got " + argumentKind + " wrapped in a " + argument.getClass().getName());
}
yield objectConstant.getValue();
}
default -> JVMCIError.shouldNotReachHere(signature.getParameterKind(i).toString());
};
}
Value result;
try {
result = vmMethodMirror.execute(args);
} catch (PolyglotException e) {
if (e.isHostException()) {
Throwable hostException = e.asHostException();
hostException.setStackTrace(e.getStackTrace());
throw new InvocationException(hostException);
}
Value guestException = e.getGuestObject();
if (guestException == null || guestException.isNull()) {View on GitHub (pinned to a66e9ccd1d)
Solutions
- For guest objects, obtain constants via the Espresso constant/snippet reflection so they are EspressoExternalObjectConstant
- For boxed types, invoke the guest valueOf method (or pass an EspressoExternalObjectConstant wrapping a guest boxed value) — no autoboxing happens implicitly
- If the reported kind is primitive, re-check argument order/arity first
Example fix
// before args[i] = JavaConstant.forInt(42); // parameter is java.lang.Integer // after JavaConstant boxed = espressoMethod.valueOf.invoke(null, JavaConstant.forInt(42)); // guest Integer.valueOf args[i] = boxed;
Defensive patterns
Strategy: validation
Validate before calling
if (signature.getParameterKind(i) == JavaKind.Object) {
JavaConstant a = args[i];
if (!a.isNull() && !(a instanceof EspressoExternalObjectConstant)) {
throw new IllegalStateException("argument " + i + " must be null or an Espresso object constant, got " + a.getClass().getName());
}
} Prevention
- No autoboxing: primitive constants never satisfy Object parameters — box via the guest valueOf method
- Host objects must be mapped to guest Values and wrapped by the Espresso constant reflection
- A primitive kind at an Object slot is the classic signature of an off-by-one argument array
When it happens
Trigger: Passing a primitive constant to a reference parameter (kind mismatch, often argument misalignment); passing a host-backend object constant (provenance mismatch); passing a primitive wrapper constant where the guest method expects a boxed java.lang.Integer (the adapter does not autobox).
Common situations: Host-to-guest bridging without converting objects to guest Values; autoboxing assumptions (int -> java.lang.Integer is not performed); overload resolution picking the boxed-parameter variant of a method.
Related errors
- Expected an espresso object receiver, got {}
- Bad receiver: expected Object, got {}
- Expected an espresso object constant, got {}
- For static methods or constructors, the receiver argument mu
- For instance methods, the receiver argument must not be null
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/16bb77092c6c2761.
Report an issue: GitHub.