oracle/graal · error · NullPointerException

For instance methods, the receiver argument must not be null

Error message

For instance methods, the receiver argument must not be null

What it means

NullPointerException thrown by EspressoExternalResolvedJavaMethod.invoke when an instance (non-static, non-constructor) method is invoked with a Java reference null receiver. The guest interop call needs an actual receiver Value to execute on, and unlike the static case there is no default; the guard fires before any marshalling. The message text is fixed ('For instance methods, the receiver argument must not be null').

Source

Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalResolvedJavaMethod.java:289

        }
        return false;
    }

    @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());

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Null-check the receiver before invoke and surface a proper error or skip the call
  2. If the intent is to trigger a guest NullPointerException, use the guest's interop path (Value.execute on a null receiver member) instead of this adapter
  3. Trace where the receiver constant became null (constant folding of a null field read is a common producer)

Example fix

// before
JavaConstant r = resolveReceiverOpt(); // may return null
method.invoke(r, args);

// after
JavaConstant r = resolveReceiverOpt();
if (r == null) {
    throw new IllegalStateException("receiver constant folded to null for " + method.getName());
}
method.invoke(r, args);
Defensive patterns

Strategy: validation

Validate before calling

if (!method.isStatic() && !method.isConstructor() && receiver == null) {
    throw new IllegalStateException("missing receiver for instance method " + method.getName());
}

Try / catch

catch (NullPointerException e) { if ("For instance methods, the receiver argument must not be null".equals(e.getMessage())) { /* recover: re-resolve receiver or report */ } else throw e; }

Prevention

When it happens

Trigger: Calling invoke(...) on a virtual/interface/special method with a null receiver variable, typically because upstream code resolved a method handle but lost the receiver object, or deliberately attempted a NullPointerException-throwing call that the adapter does not emulate.

Common situations: Null analysis or deoptimization replay tooling that reproduces an NPE-triggering call; dataflow bugs where the receiver constant is dropped; migrating code that used reflection (which throws NPE from the guest) to the JVMCI adapter (which throws it on the host side instead).

Related errors


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