oracle/graal · error · IllegalArgumentException
Illegal argument type: receiver of type {} could not be conv
Error message
Illegal argument type: receiver of type {} could not be converted to a {} What it means
Thrown by HostVMAccess.invoke for instance method invocation when the receiver constant cannot be unboxed to the method's declaring class: snippetReflection.asObject(declaringClass, receiver) returned null, i.e. the receiver object is not an instance of the class that declares the method.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:188
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;
} else {
if (receiver.isNull()) {
unboxedReceiver = null;
} else {
unboxedReceiver = snippetReflection.asObject(reflectionMethod.getDeclaringClass(), receiver);
if (unboxedReceiver == null) {
throw new IllegalArgumentException(
"Illegal argument type: receiver of type " + providers.getMetaAccess().lookupJavaType(receiver).toClassName() +
" could not be converted to a " + reflectionMethod.getDeclaringClass());
}
}
}
JavaKind returnKind = method.getSignature().getReturnKind();
Object result = reflectionMethod.invoke(unboxedReceiver, unboxedArguments);
if (returnKind == JavaKind.Void) {
return null;
}
if (returnKind.isObject()) {
return snippetReflection.forObject(result);
} else {
return snippetReflection.forBoxed(returnKind, result);
}
}
} catch (InstantiationException e) {
throw new IllegalArgumentException(e);View on GitHub (pinned to a66e9ccd1d)
Solutions
- Check the message: it names the receiver's actual class and the expected declaring class — resolve the method against the receiver's actual type (e.g. lookupJavaType(receiverObject).resolveMethod(...))
- Ensure the object you wrap is really an instance of the declaring class before forObject
- With duplicate class names across classloaders/modules, verify both sides use the same loaded class
Example fix
// before ResolvedJavaMethod m = interfaceType.resolveMethod(method); // declared on Iface hostVM.invoke(m, snippetReflection.forObject(unrelatedObj), args); // throws // after ResolvedJavaMethod m = metaAccess.lookupJavaType(receiverObj.getClass()).resolveMethod(method); hostVM.invoke(m, snippetReflection.forObject(receiverObj), args);
Defensive patterns
Strategy: type-guard
Validate before calling
Object recv = snippetReflection.asObject(reflectionMethod.getDeclaringClass(), receiver);
if (recv == null) throw new IllegalArgumentException("receiver not a " + reflectionMethod.getDeclaringClass()); Type guard
static boolean receiverMatches(ResolvedJavaMethod m, JavaConstant recv, MetaAccessProvider meta) {
return meta.lookupJavaType(recv).isSubtypeOf(m.getDeclaringClass());
} Try / catch
catch (IllegalArgumentException e) { re-resolve the method against the receiver's concrete type and retry once } Prevention
- Resolve methods via lookupJavaType(receiver.getClass()), not a hardcoded declaring type
- Beware same-named classes across classloaders/modules
- Assert receiver assignability in tests of generic invoke helpers
When it happens
Trigger: Calling invoke on an instance method with a receiver constant whose runtime class does not extend reflectionMethod.getDeclaringClass() — e.g. resolving a method on interface/superclass A but passing a receiver of unrelated class B, or passing a receiver already wrapped for the wrong type.
Common situations: Method resolution returning a default-method or bridge on an interface while the receiver is an unrelated type; classloader/module differences producing look-alike classes with the same name; refactors where the receiver expression and the resolved method drift apart.
Related errors
- Illegal argument type: arguments[{}] of type {} could not be
- Expected value kind {} but got {}
- 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
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/9699cfad995d5dcf.
Report an issue: GitHub.