{"record":{"id":"d93f59252b0e35f1","repo":"alibaba/arthas","slug":"couldn-t-find-rpcmethod","errorCode":null,"errorMessage":"Couldn't find rpcmethod: {}","messagePattern":"Couldn't find rpcmethod: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/proxy/GrpcWebRequestHandler.java","lineNumber":152,"sourceCode":"        try {\n            Method m = cls.getDeclaredMethod(stubName, io.grpc.Channel.class);\n            return (io.grpc.stub.AbstractStub) m.invoke(null, ch);\n        } catch (Exception e) {\n            logger.warn(\"Error when fetching \" + stubName + \" for: \" + cls.getName());\n            throw new IllegalArgumentException(e);\n        }\n    }\n\n    /**\n     * Find the matching method in the stub class.\n     */\n    private Method getRpcMethod(Object stub, String rpcMethodName) {\n        for (Method m : stub.getClass().getMethods()) {\n            if (m.getName().equals(rpcMethodName)) {\n                return m;\n            }\n        }\n        throw new IllegalArgumentException(\"Couldn't find rpcmethod: \" + rpcMethodName);\n    }\n\n    private static class GrpcCallResponseReceiver<Object> implements StreamObserver {\n        private final SendGrpcWebResponse sendResponse;\n        private final CountDownLatch latch;\n\n        private final ManagedChannel channel;\n\n        GrpcCallResponseReceiver(SendGrpcWebResponse s, CountDownLatch c, ManagedChannel channel) {\n            sendResponse = s;\n            latch = c;\n            this.channel = channel;\n        }\n\n        @Override\n        public void onNext(java.lang.Object resp) {\n            // TODO verify that the resp object is of Class instance returnedCls.\n            byte[] outB = ((com.google.protobuf.GeneratedMessageV3) resp).toByteArray();","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/proxy/GrpcWebRequestHandler.java#L134-L170","documentation":"GrpcWebRequestHandler.getRpcMethod() throws IllegalArgumentException when no method on the resolved gRPC stub class matches the requested rpcMethodName. The proxy iterates the stub's public methods via reflection; a miss means the method name derived from the URL doesn't correspond to any generated RPC method.","triggerScenarios":"The URL specifies a method name that does not exist on the target gRPC stub class — e.g. a typo, a renamed method, or a method from a different service.","commonSituations":"Client uses an outdated method name after a proto schema change; method name casing mismatch after the proxy's lowercasing of the first character; the stub class was generated from a different .proto than the client expects; the class resolved isn't the intended gRPC service stub.","solutions":["Verify the method name in the URL matches a real method on the generated *Grpc stub class.","Regenerate the gRPC stubs from the current .proto and redeploy both client and server.","Check for first-character-casing issues: the proxy lowercases the first char of the method name; ensure the actual stub method name matches that convention.","Confirm the class segment of the URL resolves to the correct service (not a similarly-named class)."],"exampleFix":"// before: method renamed from getData to fetchData in proto\n// URL: /MyService/getData  -> throws 'Couldn't find rpcmethod: fetchData'\n\n// after: update client to use the new method name\n// URL: /MyService/fetchData","handlingStrategy":"validation","validationCode":"// Verify the method exists on the stub before invoking\nboolean exists = Arrays.stream(stub.getClass().getMethods())\n    .anyMatch(m -> m.getName().equals(rpcMethodName));\nif (!exists) {\n    sendResponse.writeError(Status.UNIMPLEMENTED\n        .withDescription(\"Unknown RPC method: \" + rpcMethodName));\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    Method m = getRpcMethod(stub, rpcMethodName);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Couldn't find rpcmethod\")) {\n        sendResponse.writeError(Status.UNIMPLEMENTED.withDescription(e.getMessage()));\n    } else { throw e; }\n}","preventionTips":["Keep client and server proto definitions in sync to avoid method-name drift.","Return a clear UNIMPLEMENTED status to the client on unknown methods instead of crashing."],"tags":["arthas","grpc-web-proxy","reflection","method-resolution","proto"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}