{"record":{"id":"a8ccf04e518f1221","repo":"oracle/graal","slug":"for-instance-methods-the-receiver-argument-must-n","errorCode":null,"errorMessage":"For instance methods, the receiver argument must not be null","messagePattern":"For instance methods, the receiver argument must not be null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java","lineNumber":145,"sourceCode":"\n    @Override\n    public boolean owns(ResolvedJavaField value) {\n        return value.getClass().getModule() == hostImplModule;\n    }\n\n    @Override\n    public JavaConstant invoke(ResolvedJavaMethod method, JavaConstant receiver, JavaConstant... arguments) {\n        SnippetReflectionProvider snippetReflection = providers.getSnippetReflection();\n        Executable executable = snippetReflection.originalMethod(method);\n        makeAccessible(executable);\n        boolean isConstructor = executable instanceof Constructor;\n        Class<?>[] parameterTypes = executable.getParameterTypes();\n        if (Modifier.isStatic(executable.getModifiers()) || isConstructor) {\n            if (receiver != null) {\n                throw new IllegalArgumentException(\"For static methods or constructor, the receiver argument must be null\");\n            }\n        } else if (receiver == null) {\n            throw new NullPointerException(\"For instance methods, the receiver argument must not be null\");\n        } else if (receiver.isNull()) {\n            throw new IllegalArgumentException(\"For instance methods, the receiver argument must not represent a null constant\");\n        }\n        if (parameterTypes.length != arguments.length) {\n            throw new IllegalArgumentException(\"Wrong number of arguments: expected \" + parameterTypes.length + \" but got \" + arguments.length);\n        }\n        Signature signature = method.getSignature();\n        Object[] unboxedArguments = new Object[parameterTypes.length];\n        for (int i = 0; i < unboxedArguments.length; i++) {\n            JavaKind parameterKind = signature.getParameterKind(i);\n            JavaConstant argument = arguments[i];\n            if (parameterKind.isObject()) {\n                if (argument.isNull()) {\n                    unboxedArguments[i] = null;\n                } else {\n                    unboxedArguments[i] = snippetReflection.asObject(parameterTypes[i], argument);\n                    if (unboxedArguments[i] == null) {\n                        throw new IllegalArgumentException(","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java#L127-L163","documentation":"Thrown (as NullPointerException) by HostVMAccess.invoke when an instance method is invoked with a null receiver reference. The host VM needs an actual object to dispatch on, and unlike the null-constant case this one is a programming error (null literal passed) rather than a bad constant value.","triggerScenarios":"Calling invoke(instanceMethod, null, args...) where instanceMethod maps to a non-static, non-constructor Executable. The preceding branch already ensures static/constructor calls got null legally; reaching this throw means an instance method got a literal null receiver.","commonSituations":"A caller-side conditional that defaults the receiver to null (e.g. receiver = cond ? forObject(x) : null) then invokes an instance method on the null path; refactoring a static call site into an instance one without updating receiver construction.","solutions":["Construct and pass a real receiver constant: snippetReflection.forObject(targetObject)","Ensure the method you resolved is the one you think — if it should be static, re-check the original method","Default the receiver to forObject(...) rather than null in shared call paths"],"exampleFix":"// before\nJavaConstant receiver = useReceiver ? snippetReflection.forObject(obj) : null;\nhostVM.invoke(instanceMethod, receiver, args);  // throws NPE when useReceiver==false\n\n// after\nhostVM.invoke(instanceMethod, snippetReflection.forObject(obj), args);","handlingStrategy":"validation","validationCode":"if (!Modifier.isStatic(executable.getModifiers()) && receiver == null) {\n    throw new NullPointerException(\"receiver required for \" + executable);","typeGuard":null,"tryCatchPattern":"catch (NullPointerException e) { surface which method lacked a receiver; fix the call site }","preventionTips":["Require non-null holder objects for instance invocation at the API boundary","Avoid null-defaulting ternaries for receivers in shared paths","Unit-test both static and instance paths of generic invoke helpers"],"tags":["graalvm","hostvmaccess","reflection","null-safety"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}