oracle/graal · error · IllegalArgumentException
Wrong number of arguments: expected {} but got {}
Error message
Wrong number of arguments: expected {} but got {} What it means
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.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:150
@Override
public JavaConstant invoke(ResolvedJavaMethod method, JavaConstant receiver, JavaConstant... arguments) {
SnippetReflectionProvider snippetReflection = providers.getSnippetReflection();
Executable executable = snippetReflection.originalMethod(method);
makeAccessible(executable);
boolean isConstructor = executable instanceof Constructor;
Class<?>[] parameterTypes = executable.getParameterTypes();
if (Modifier.isStatic(executable.getModifiers()) || isConstructor) {
if (receiver != null) {
throw new IllegalArgumentException("For static methods or constructor, the receiver argument must be null");
}
} else if (receiver == null) {
throw new NullPointerException("For instance methods, the receiver argument must not be null");
} else if (receiver.isNull()) {
throw new IllegalArgumentException("For instance methods, the receiver argument must not represent a null constant");
}
if (parameterTypes.length != arguments.length) {
throw new IllegalArgumentException("Wrong number of arguments: expected " + parameterTypes.length + " but got " + arguments.length);
}
Signature signature = method.getSignature();
Object[] unboxedArguments = new Object[parameterTypes.length];
for (int i = 0; i < unboxedArguments.length; i++) {
JavaKind parameterKind = signature.getParameterKind(i);
JavaConstant argument = arguments[i];
if (parameterKind.isObject()) {
if (argument.isNull()) {
unboxedArguments[i] = null;
} else {
unboxedArguments[i] = snippetReflection.asObject(parameterTypes[i], argument);
if (unboxedArguments[i] == null) {
throw new IllegalArgumentException(
"Illegal argument type: arguments[" + i + "] of type " + providers.getMetaAccess().lookupJavaType(arguments[i]).toClassName() +
" could not be converted to a " + parameterTypes[i]);
}
}
} else {View on GitHub (pinned to a66e9ccd1d)
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
Example fix
// before hostVM.invoke(instanceMethod, null, arg0, arg1); // receiver leaked into varargs hostVM.invoke(twoArgMethod, receiver, onlyArg0); // missing arg // after hostVM.invoke(instanceMethod, forObject(obj), arg0, arg1); hostVM.invoke(twoArgMethod, receiver, arg0, arg1);
Defensive patterns
Strategy: validation
Validate before calling
if (executable.getParameterCount() != arguments.length) {
throw new IllegalArgumentException("arity mismatch for " + executable); Try / catch
catch (IllegalArgumentException e) { log expected vs got counts; regenerate the argument list } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- For static methods or constructor, the receiver argument mus
- For instance methods, the receiver argument must not be null
- For instance methods, the receiver argument must not represe
- Illegal argument type: arguments[{}] of type {} could not be
- Illegal argument type: receiver of type {} could not be conv
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/599f170a794848ac.
Report an issue: GitHub.