{"record":{"id":"587d841d30619a75","repo":"alibaba/arthas","slug":"incorrect-pathinfo","errorCode":null,"errorMessage":"incorrect pathinfo: {}","messagePattern":"incorrect pathinfo: (.+?)","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":114,"sourceCode":"                inObj = MessageUtils.getInputProtobufObj(asyncStubCall, deframer.getMessageBytes());\n            }\n            ManagedChannel managedChannel = grpcServiceConnectionManager.getChannel();\n            // Invoke the rpc call\n            asyncStubCall.invoke(asyncStub, inObj, new GrpcCallResponseReceiver(sendResponse, latch,managedChannel));\n            if (!latch.await( 1000, TimeUnit.MILLISECONDS)) {\n                logger.warn(\"grpc call took too long!\");\n            }\n        } catch (Exception e) {\n            logger.error(\"try to invoke grpc serivce error, uri: {}\", req.uri(), e);\n            sendResponse.writeError(Status.UNAVAILABLE.withCause(e));\n        }\n    }\n\n    private Pair<String, String> getClassAndMethod(String pathInfo) throws IllegalArgumentException {\n        // pathInfo starts with \"/\". ignore that first char.\n        String[] rpcClassAndMethodTokens = pathInfo.substring(1).split(\"/\");\n        if (rpcClassAndMethodTokens.length != 2) {\n            throw new IllegalArgumentException(\"incorrect pathinfo: \" + pathInfo);\n        }\n\n        String rpcClassName = rpcClassAndMethodTokens[0];\n        String rpcMethodNameRecvd = rpcClassAndMethodTokens[1];\n        String rpcMethodName = rpcMethodNameRecvd.substring(0, 1).toLowerCase() + rpcMethodNameRecvd.substring(1);\n        return new Pair<>(rpcClassName, rpcMethodName);\n    }\n\n    private Class<?> getClassObject(String className) {\n        Class rpcClass = null;\n        try {\n            rpcClass = Class.forName(className + \"Grpc\");\n        } catch (ClassNotFoundException e) {\n            logger.info(\"no such class \" + className);\n        }\n        return rpcClass;\n    }\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/proxy/GrpcWebRequestHandler.java#L96-L132","documentation":"GrpcWebRequestHandler.getClassAndMethod() throws IllegalArgumentException when the gRPC web proxy URL pathInfo does not split into exactly two tokens (class and method). The proxy expects a path of the form '/ClassName/methodName'; any other shape is malformed.","triggerScenarios":"The incoming HTTP request URI path (after stripping the leading '/') splits on '/' into fewer or more than 2 segments — e.g. '/ClassName', '/a/b/c', or an empty path.","commonSituations":"A client hits the proxy root or a wrong endpoint path; the reverse proxy/ingress rewrites the path incorrectly, adding or removing segments; the gRPC-web encoding strips part of the path; a misconfigured service URL with extra or missing path components.","solutions":["Correct the client request URL to the '/ClassName/methodName' format expected by the proxy.","Check the reverse proxy / ingress path-rewrite rules to ensure the original two-segment path is preserved.","Log the incoming pathInfo at DEBUG level to see exactly what the proxy receives and trace where it diverges."],"exampleFix":"// before: client sends wrong path\n// GET /grpc-web/ClassName  (missing method)\n\n// after: include both segments\n// GET /grpc-web/ClassName/methodName","handlingStrategy":"validation","validationCode":"String[] tokens = pathInfo.substring(1).split(\"/\");\nif (tokens.length != 2) {\n    throw new IllegalArgumentException(\n        \"Path must be '/ClassName/methodName', got: \" + pathInfo);\n}\n// proceed to getClassAndMethod(pathInfo)","typeGuard":null,"tryCatchPattern":"try {\n    handler.handle(req);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"incorrect pathinfo\")) {\n        sendResponse.writeError(Status.INVALID_ARGUMENT.withDescription(e.getMessage()));\n    } else { throw e; }\n}","preventionTips":["Document and enforce the '/ClassName/methodName' path convention on the client side.","Validate request paths at the ingress/reverse-proxy layer before they reach the handler."],"tags":["arthas","grpc-web-proxy","request-routing","url-path","validation"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}