oracle/graal · error · IllegalArgumentException
For instance methods, the receiver argument must not represe
Error message
For instance methods, the receiver argument must not represent a null constant
What it means
Thrown by EspressoExternalResolvedJavaMethod.invoke when an instance method is invoked with a JavaConstant that represents null (isNull() == true) rather than a Java null reference. The adapter distinguishes a missing receiver (NPE, previous guard) from a present-but-null constant: even if you wrap null in a constant object, interop execution on a null guest Value is impossible, so it rejects with IllegalArgumentException. This catches constants produced by JavaConstant.NULL_POINTER or equivalent null-representing constants from another backend.
Source
Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaMethod.java:291
}
@Override
protected int hashCode0() {
return vmMethodMirror.hashCode();
}
/// Adapts a call to a guest Espresso method, converting between [JavaConstant] values and
/// the polyglot [Value]s, and back. The interop implementation in the Espresso is
/// `com.oracle.truffle.espresso.impl.Method.Execute#invoke`.
JavaConstant invoke(JavaConstant receiver, JavaConstant... arguments) {
if (isStatic() || isConstructor()) {
if (receiver != null) {
throw new IllegalArgumentException("For static methods or constructors, 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");
}
AbstractEspressoSignature signature = getSignature();
int parameterCount = signature.getParameterCount(false);
if (parameterCount != arguments.length) {
throw new IllegalArgumentException("Expected " + parameterCount + " arguments, got " + arguments.length);
}
Object[] args = new Object[arguments.length + (isConstructor() || !isStatic() ? 1 : 0)];
int outputArgumentOffset = 0;
EspressoExternalVMAccess access = getAccess();
if (isConstructor()) {
EspressoExternalResolvedInstanceType type = (EspressoExternalResolvedInstanceType) getDeclaringClass();
args[0] = access.unsafeAllocateInstance(type).getValue();
outputArgumentOffset = 1;
} else if (!isStatic()) {
if (!(receiver instanceof EspressoExternalObjectConstant objectConstant)) {
throw new IllegalArgumentException("Bad receiver: expected Object, got " + arguments[0].getJavaKind());
}
args[0] = objectConstant.getValue();View on GitHub (pinned to a66e9ccd1d)
Solutions
- Convert null-representing constants to a Java null reference before calling invoke (receiver.isNull() ? null : receiver)
- If the goal is a guest NPE, execute through the guest polyglot Value API rather than the JVMCI adapter
- Audit producers that return JavaConstant.NULL_POINTER where callers expect nullable Java references
Example fix
// before JavaConstant receiver = provider.forObject(null); // NULL_POINTER constant method.invoke(receiver, args); // after JavaConstant receiver = provider.forObject(null); method.invoke(receiver.isNull() ? null : receiver, args); // adapter NPE path is explicit
Defensive patterns
Strategy: validation
Validate before calling
if (receiver != null && receiver.isNull()) {
throw new IllegalStateException("null constant receiver for " + method.getName() + " — pass Java null or fix upstream");
} Prevention
- Normalize null-representing constants to Java null before invoke
- Do not use JavaConstant.NULL_POINTER or foreign null constants as receivers
- Distinguish 'no receiver' (static/constructor contract) from 'null receiver' (always invalid here) in your calling conventions
When it happens
Trigger: Passing JavaConstant.NULL_POINTER (or a foreign backend's null constant) as the receiver to an instance method invoke; constants obtained from ConstantReflectionProvider forObject(null)-style APIs; defaulted constants (isDefaultForKind) reused as receivers.
Common situations: Uniform constant pipelines that represent 'absent object' as a null constant instead of a Java null; replayer/snapshot tools that serialize receivers and deserialize null as a constant; guest code that legitimately calls a method on null and the harness forwards the null constant verbatim.
Related errors
- For static methods or constructors, the receiver argument mu
- Bad receiver: expected Object, got {}
- For instance methods, the receiver argument must not be null
- Expected {} arguments, got {}
- Bad argument kind at index {}: expected Boolean, got {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/091a287c1821ddfd.
Report an issue: GitHub.