oracle/graal · error · IllegalArgumentException
Bad argument kind at index {}: expected Double, got {}
Error message
Bad argument kind at index {}: expected Double, got {} What it means
Thrown by the argument marshalling switch in EspressoExternalResolvedJavaMethod.invoke when a parameter is declared double but the argument constant's kind is not in {Long, Int, Char, Short, Byte, Float, Double}. This is the widest numeric acceptance set (everything numeric widens to double, JLS 5.1.2); only Boolean and Object constants are rejected, since neither is convertible to double under strict invocation. Hitting it usually means an argument order problem or a wrong method resolved rather than a genuine conversion gap.
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaMethod.java:361
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Int, got " + argumentKind);
};
case Long -> switch (argumentKind) {
case Long, Int, Char, Short, Byte -> argument.asLong();
default ->
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Long, got " + argumentKind);
};
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) {View on GitHub (pinned to a66e9ccd1d)
Solutions
- Recheck argument alignment: receiver excluded, arity equals getParameterCount(false), each constant matches its parameter position
- Verify the resolved ResolvedJavaMethod is the intended overload (compare name and signature)
- Convert Boolean constants to a numeric double explicitly if the guest API really takes double for a truth flag
Example fix
// before: receiver accidentally left in args
JavaConstant[] args = {receiver, JavaConstant.forDouble(x)};
method.invoke(null, args); // instance method -> misaligned
// after
JavaConstant[] args = {JavaConstant.forDouble(x)};
method.invoke(receiver, args); Defensive patterns
Strategy: validation
Validate before calling
JavaKind ak = args[i].getJavaKind();
boolean numeric = ak == JavaKind.Double || ak == JavaKind.Float || ak == JavaKind.Long || ak == JavaKind.Int || ak == JavaKind.Char || ak == JavaKind.Short || ak == JavaKind.Byte;
if (signature.getParameterKind(i) == JavaKind.Double && !numeric) {
throw new IllegalStateException("argument " + i + " not numeric for double parameter");
} Prevention
- Double accepts every numeric kind; Boolean/Object rejections almost always indicate misaligned arguments
- Check receiver exclusion and arity whenever this fires
- Verify overload resolution when a method has boxed/unboxed variants
When it happens
Trigger: Passing a Boolean constant to a double parameter; passing an EspressoExternalObjectConstant (object) where a double is declared; argument array shifted by including the receiver or dropping an argument.
Common situations: Off-by-one argument alignment after adapting from java.lang.reflect.Method.invoke; resolving an overload with a different signature than intended; polymorphic call sites mis-dispatched.
Related errors
- Bad argument kind at index {}: expected Boolean, got {}
- Bad argument kind at index {}: expected Byte, got {}
- Bad argument kind at index {}: expected Char, got {}
- Bad argument kind at index {}: expected Short, got {}
- Bad argument kind at index {}: expected Int, got {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/ae78624292838dbb.
Report an issue: GitHub.