{"record":{"id":"16bb77092c6c2761","repo":"oracle/graal","slug":"bad-argument-kind-at-index-expected-object-go","errorCode":null,"errorMessage":"Bad argument kind at index {}: expected Object, got {} wrapped in a {}","messagePattern":"Bad argument kind at index (.+?): expected Object, got (.+?) wrapped in a (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaMethod.java","lineNumber":368,"sourceCode":"                case Float -> switch (argumentKind) {\n                    case Long, Int, Char, Short, Byte -> (float) argument.asLong();\n                    case Float -> argument.asFloat();\n                    default ->\n                        throw new IllegalArgumentException(\"Bad argument kind at index \" + i + \": expected Float, got \" + argumentKind);\n                };\n                case Double -> switch (argumentKind) {\n                    case Long, Int, Char, Short, Byte -> (double) argument.asLong();\n                    case Float -> (double) argument.asFloat();\n                    case Double -> argument.asDouble();\n                    default ->\n                        throw new IllegalArgumentException(\"Bad argument kind at index \" + i + \": expected Double, got \" + argumentKind);\n                };\n                case Object -> {\n                    if (argument.isNull()) {\n                        yield null;\n                    }\n                    if (!(argument instanceof EspressoExternalObjectConstant objectConstant)) {\n                        throw new IllegalArgumentException(\n                                        \"Bad argument kind at index \" + i + \": expected Object, got \" + argumentKind + \" wrapped in a \" + argument.getClass().getName());\n                    }\n                    yield objectConstant.getValue();\n                }\n                default -> JVMCIError.shouldNotReachHere(signature.getParameterKind(i).toString());\n            };\n        }\n        Value result;\n        try {\n            result = vmMethodMirror.execute(args);\n        } catch (PolyglotException e) {\n            if (e.isHostException()) {\n                Throwable hostException = e.asHostException();\n                hostException.setStackTrace(e.getStackTrace());\n                throw new InvocationException(hostException);\n            }\n            Value guestException = e.getGuestObject();\n            if (guestException == null || guestException.isNull()) {","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaMethod.java#L350-L386","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nargs[i] = JavaConstant.forInt(42); // parameter is java.lang.Integer\n\n// after\nJavaConstant boxed = espressoMethod.valueOf.invoke(null, JavaConstant.forInt(42)); // guest Integer.valueOf\nargs[i] = boxed;","handlingStrategy":"validation","validationCode":"if (signature.getParameterKind(i) == JavaKind.Object) {\n    JavaConstant a = args[i];\n    if (!a.isNull() && !(a instanceof EspressoExternalObjectConstant)) {\n        throw new IllegalStateException(\"argument \" + i + \" must be null or an Espresso object constant, got \" + a.getClass().getName());\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["espresso","jvmci","method-invocation","boxing","type-mismatch","polyglot"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}