{"record":{"id":"6929c98a471918d7","repo":"apache/hadoop","slug":"null-param-while-calling-method-6929c9","errorCode":null,"errorMessage":"null param while calling Method: [{}]","messagePattern":"null param while calling Method: \\[(.+?)\\]","errorType":"validation","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProtobufRpcEngine2.java","lineNumber":236,"sourceCode":"     * cause is RemoteException, then unwrap it to get the exception thrown by\n     * the server.\n     */\n    @Override\n    public Message invoke(Object proxy, final Method method, Object[] args)\n        throws ServiceException {\n      long startTime = 0;\n      if (LOG.isDebugEnabled()) {\n        startTime = Time.monotonicNow();\n      }\n\n      if (args.length != 2) { // RpcController + Message\n        throw new ServiceException(\n            \"Too many or few parameters for request. Method: [\"\n            + method.getName() + \"]\" + \", Expected: 2, Actual: \"\n            + args.length);\n      }\n      if (args[1] == null) {\n        throw new ServiceException(\"null param while calling Method: [\"\n            + method.getName() + \"]\");\n      }\n\n      // if Tracing is on then start a new span for this rpc.\n      // guard it in the if statement to make sure there isn't\n      // any extra string manipulation.\n      Tracer tracer = Tracer.curThreadTracer();\n      TraceScope traceScope = null;\n      if (tracer != null) {\n        traceScope = tracer.newScope(RpcClientUtil.methodToTraceString(method));\n      }\n\n      if (LOG.isTraceEnabled()) {\n        LOG.trace(Thread.currentThread().getId() + \": Call -> \" +\n            remoteId + \": \" + method.getName() +\n            \" {\" + TextFormat.shortDebugString((Message) args[1]) + \"}\");\n      }\n","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProtobufRpcEngine2.java#L218-L254","documentation":"ProtobufRpcEngine2's InvocationHandler rejects a null request message (args[1] == null) with ServiceException('null param while calling Method: [m]') because protobuf messages cannot be null on the wire — there is always at least a default instance. Thrown client-side, before a connection is made.","triggerScenarios":"Calling proxy.method(controller, null); a request-builder helper returning null on validation failure and being forwarded; argument-order mix-ups where null lands in the message slot.","commonSituations":"Test harnesses stubbing request construction; wrapper APIs with optional parameters defaulted to null; refactors from WritableRpcEngine (where null params were sometimes tolerated) to protobuf.","solutions":["Pass Message.getDefaultInstance() for 'empty' requests.","Make request-builder helpers never return null — throw or return the default instance.","Add Objects.requireNonNull(request) at the wrapper boundary for a clearer failure."],"exampleFix":"// before\nproxy.rename(null, null); // null request -> ServiceException\n\n// after\nproxy.rename(null,\n    RenameRequestProto.newBuilder()\n        .setSrc(\"/a\").setDst(\"/b\").build());","handlingStrategy":"validation","validationCode":"java.util.Objects.requireNonNull(request,\n    \"protobuf request for \" + method.getName() + \" must not be null; use getDefaultInstance() if empty\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never forward possibly-null messages; substitute the default instance.","Use builder-helper APIs that always yield a built message.","Objects.requireNonNull at the boundary gives a better stack than the engine's generic error."],"tags":["hadoop","ipc","rpc","protobuf","null-argument","validation"],"backgroundTag":"null-argument-rejected","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}