oracle/graal · error · IllegalArgumentException

Illegal argument type: arguments[{}] of type {} could not be

Error message

Illegal argument type: arguments[{}] of type {} could not be converted to a {}

What it means

Thrown by HostVMAccess.invoke when an object-typed argument constant cannot be unboxed to the declared parameter type: SnippetReflectionProvider.asObject(parameterType, argument) returned null, meaning the constant's runtime type is not assignable to the parameter. The message reports the offending index, the constant's actual class, and the expected parameter type.

Source

Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:163

            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 {
                assert parameterKind.isPrimitive();
                unboxedArguments[i] = argument.asBoxedPrimitive();
            }
        }
        try {
            if (isConstructor) {
                Constructor<?> constructor = (Constructor<?>) executable;
                return snippetReflection.forObject(constructor.newInstance(unboxedArguments));
            } else {
                Method reflectionMethod = (Method) executable;
                Object unboxedReceiver;
                if (Modifier.isStatic(reflectionMethod.getModifiers())) {
                    unboxedReceiver = null;

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Read the message: it names arguments[i]'s actual class and the expected parameter type — convert the value before wrapping (e.g. cast/convert String to Integer)
  2. Verify you resolved the intended overload; pick the overload whose parameter type matches your constant
  3. For primitives, ensure the constant kind is primitive so the asBoxedPrimitive path is taken instead of the object path

Example fix

// before
// target: void set(int v)
hostVM.invoke(setMethod, receiver, snippetReflection.forObject("42"));  // String vs int param -> throws

// after
hostVM.invoke(setMethod, receiver, JavaConstant.forInt(42));
Defensive patterns

Strategy: type-guard

Validate before calling

for (int i = 0; i < args.length; i++) {
    if (parameterTypes[i].isPrimitive() != args[i].getJavaKind().isPrimitive()) {
        throw new IllegalArgumentException("kind mismatch at " + i);
    }
}

Type guard

static boolean argMatches(JavaConstant c, Class<?> p, MetaAccessProvider m) {
    return p.isInstance(m.getSnippetReflection() != null ? null : null); // use snippetReflection.asObject(p, c) != null as the real guard
}

Try / catch

catch (IllegalArgumentException e) { parse the message for index/actual/expected types and convert the value accordingly }

Prevention

When it happens

Trigger: Calling invoke with arguments[i] whose wrapped object's class is incompatible with parameterTypes[i] — e.g. passing a String constant for an Integer parameter, or an object from a different class hierarchy. asObject only succeeds when the constant's type matches/extends the requested type.

Common situations: Building argument constants from folded snippet values whose static type is Object, version changes where a library method's parameter type was narrowed, or boxing mismatches (passing the boxed wrapper when a primitive overload vs object overload exist — the primitive path is handled by asBoxedPrimitive, so this throw means the wrong overload was selected).

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/68d5a0bdd9e38455. Report an issue: GitHub.