{"record":{"id":"599f170a794848ac","repo":"oracle/graal","slug":"wrong-number-of-arguments-expected-but-got","errorCode":null,"errorMessage":"Wrong number of arguments: expected {} but got {}","messagePattern":"Wrong number of arguments: expected (.+?) but got (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java","lineNumber":150,"sourceCode":"\n    @Override\n    public JavaConstant invoke(ResolvedJavaMethod method, JavaConstant receiver, JavaConstant... arguments) {\n        SnippetReflectionProvider snippetReflection = providers.getSnippetReflection();\n        Executable executable = snippetReflection.originalMethod(method);\n        makeAccessible(executable);\n        boolean isConstructor = executable instanceof Constructor;\n        Class<?>[] parameterTypes = executable.getParameterTypes();\n        if (Modifier.isStatic(executable.getModifiers()) || isConstructor) {\n            if (receiver != null) {\n                throw new IllegalArgumentException(\"For static methods or constructor, the receiver argument must be null\");\n            }\n        } else if (receiver == null) {\n            throw new NullPointerException(\"For instance methods, the receiver argument must not be null\");\n        } else if (receiver.isNull()) {\n            throw new IllegalArgumentException(\"For instance methods, the receiver argument must not represent a null constant\");\n        }\n        if (parameterTypes.length != arguments.length) {\n            throw new IllegalArgumentException(\"Wrong number of arguments: expected \" + parameterTypes.length + \" but got \" + arguments.length);\n        }\n        Signature signature = method.getSignature();\n        Object[] unboxedArguments = new Object[parameterTypes.length];\n        for (int i = 0; i < unboxedArguments.length; i++) {\n            JavaKind parameterKind = signature.getParameterKind(i);\n            JavaConstant argument = arguments[i];\n            if (parameterKind.isObject()) {\n                if (argument.isNull()) {\n                    unboxedArguments[i] = null;\n                } else {\n                    unboxedArguments[i] = snippetReflection.asObject(parameterTypes[i], argument);\n                    if (unboxedArguments[i] == null) {\n                        throw new IllegalArgumentException(\n                                        \"Illegal argument type: arguments[\" + i + \"] of type \" + providers.getMetaAccess().lookupJavaType(arguments[i]).toClassName() +\n                                                        \" could not be converted to a \" + parameterTypes[i]);\n                    }\n                }\n            } else {","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java#L132-L168","documentation":"Thrown by HostVMAccess.invoke when the number of argument constants does not match the reflective parameter count of the target executable. The host VM unboxes arguments positionally, so arity must match exactly before any conversion is attempted.","triggerScenarios":"Calling invoke(method, receiver, args...) where args.length != executable.getParameterTypes().length — e.g. passing a receiver inside the varargs array for an instance method, forgetting a varargs spread, or dropping trailing arguments.","commonSituations":"Migrating call sites between APIs where the receiver is positional vs separate; handling signature-polymorphic or varargs methods whose reflective parameter count differs from source-level arity; stale hardcoded argument lists after a target method signature change.","solutions":["Log both numbers from the exception and fix the argument array to match parameterTypes.length","For instance methods make sure the receiver goes in the receiver parameter, not arguments[]","For varargs targets, pass the trailing array as a single argument constant or expand it to match the declared arity","Re-resolve the method after signature changes instead of caching old arity assumptions"],"exampleFix":"// before\nhostVM.invoke(instanceMethod, null, arg0, arg1);          // receiver leaked into varargs\nhostVM.invoke(twoArgMethod, receiver, onlyArg0);            // missing arg\n\n// after\nhostVM.invoke(instanceMethod, forObject(obj), arg0, arg1);\nhostVM.invoke(twoArgMethod, receiver, arg0, arg1);","handlingStrategy":"validation","validationCode":"if (executable.getParameterCount() != arguments.length) {\n    throw new IllegalArgumentException(\"arity mismatch for \" + executable);","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) { log expected vs got counts; regenerate the argument list }","preventionTips":["Compute arity from the resolved executable, never hardcode","Keep the receiver out of arguments[]","Re-resolve methods after signature changes; add arity assertions in test harnesses"],"tags":["graalvm","hostvmaccess","reflection","arity"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}