oracle/graal · error · IllegalArgumentException
Bad argument kind at index {}: expected Boolean, got {}
Error message
Bad argument kind at index {}: expected Boolean, got {} What it means
Thrown by EspressoExternalResolvedJavaMethod.invoke's argument marshalling switch when a parameter is declared boolean but the supplied JavaConstant's JavaKind is not Boolean. Unlike the numeric kinds, boolean is not part of JVMCI's widening lattice (booleans are not widened to int in strict invocation, JLS 5.3), so the adapter accepts only an exact Boolean constant and rejects anything else with the parameter index and actual kind in the message.
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaMethod.java:323
} else if (!isStatic()) {
if (!(receiver instanceof EspressoExternalObjectConstant objectConstant)) {
throw new IllegalArgumentException("Bad receiver: expected Object, got " + arguments[0].getJavaKind());
}
args[0] = objectConstant.getValue();
outputArgumentOffset = 1;
}
for (int i = 0; i < parameterCount; i++) {
JavaConstant argument = arguments[i];
JavaKind argumentKind = argument.getJavaKind();
/*
* Perform widening primitive conversions (JLS 5.1.2) in order to implement strict
* method invocation conversions (JLS 5.3). Also promote to stack kind.
*/
args[i + outputArgumentOffset] = switch (signature.getParameterKind(i)) {
case Boolean -> switch (argumentKind) {
case Boolean -> argument.asBoolean() ? 1 : 0;
default ->
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Boolean, got " + argumentKind);
};
case Byte -> switch (argumentKind) {
case Byte -> argument.asInt();
default ->
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Byte, got " + argumentKind);
};
case Char -> switch (argumentKind) {
case Char -> argument.asInt();
default ->
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Char, got " + argumentKind);
};
case Short -> switch (argumentKind) {
case Short, Byte -> argument.asInt();
default ->
throw new IllegalArgumentException("Bad argument kind at index " + i + ": expected Short, got " + argumentKind);
};
case Int -> switch (argumentKind) {
case Int, Char, Short, Byte -> argument.asInt();View on GitHub (pinned to a66e9ccd1d)
Solutions
- Convert to JavaConstant.forBoolean(...) at the boundary: check signature.getParameterKind(i)==Boolean and box accordingly
- Keep a kind-conversion table mirroring the adapter's switch (Boolean accepts only Boolean) instead of assuming numeric coercion
- Fix the producer that promoted the boolean constant to Int
Example fix
// before args[i] = JavaConstant.forInt(flag ? 1 : 0); method.invoke(receiver, args); // after args[i] = JavaConstant.forBoolean(flag); method.invoke(receiver, args);
Defensive patterns
Strategy: validation
Validate before calling
if (signature.getParameterKind(i) == JavaKind.Boolean && args[i].getJavaKind() != JavaKind.Boolean) {
args[i] = JavaConstant.forBoolean(args[i].asInt() != 0);
} Prevention
- Booleans are never coerced here: only exact Boolean constants are accepted
- Watch for Int-kind constants that were subword-promoted earlier in the pipeline
- Centralize argument adaptation in a converter mirroring the adapter's switch
When it happens
Trigger: Passing JavaConstant.forInt(0/1), a boxed Boolean wrapped in the wrong constant type, or an Int-kind constant (common because JVMCI promotes subword kinds) to a boolean parameter at the reported index.
Common situations: Constants normalized to Int kind by earlier pipeline stages (stack-kind promotion), replay files that encode booleans as integers, language bridges mapping truthy values to ints.
Related errors
- 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 {}
- Bad argument kind at index {}: expected Long, got {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/4d95eddd84b6e966.
Report an issue: GitHub.