{"record":{"id":"941a772d06488a25","repo":"theonedev/onedev","slug":"invalid-request-path-941a77","errorCode":null,"errorMessage":"Invalid request path","messagePattern":"Invalid request path","errorType":"http","errorClass":"ClientException","httpStatus":400,"severity":"error","filePath":"server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java","lineNumber":149,"sourceCode":"\tprivate byte[] decodeHex(String hexString) {\n\t\ttry {\n\t\t\treturn Hex.decodeHex(hexString);\n\t\t} catch (DecoderException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t}\n\t}\n\t\n\t@Override\n\tpublic void handle(HttpServletRequest request, HttpServletResponse response, Long projectId, \n\t\t\t\t\t\tLong buildId, List<String> pathSegments) {\n\t\tvar method = request.getMethod();\n\t\t\n\t\tvar isGet = method.equals(\"GET\");\n\t\tvar isPut = method.equals(\"PUT\");\n\t\tvar isDelete = method.equals(\"DELETE\");\n\t\t\n\t\tif (pathSegments.isEmpty())\n\t\t\tthrow new ClientException(SC_BAD_REQUEST, \"Invalid request path\");\n\t\t\n\t\tvar currentSegment = pathSegments.get(0);\n\t\tif (currentSegment.equals(\"-\")) {\n\t\t\tpathSegments = pathSegments.subList(1, pathSegments.size());\n\t\t\tif (pathSegments.isEmpty())\n\t\t\t\tthrow new ClientException(SC_BAD_REQUEST, \"Invalid request path\");\t\t\t\t\n\t\t\tcurrentSegment = pathSegments.get(0);\n\t\t\tpathSegments = pathSegments.subList(1, pathSegments.size());\n\t\t\tif (currentSegment.equals(\"package\")) {\n\t\t\t\tif (pathSegments.size() >= 2) {\n\t\t\t\t\tvar packageName = decodePath(pathSegments.get(0));\n\t\t\t\t\tif (pathSegments.get(1).equals(\"dist-tags\")) {\n\t\t\t\t\t\tif (pathSegments.size() == 2) {\n\t\t\t\t\t\t\tif (isGet) {\n\t\t\t\t\t\t\t\tsessionService.run(() -> {\n\t\t\t\t\t\t\t\t\tvar project = checkProject(projectId, false);\n\t\t\t\t\t\t\t\t\tvar packs = packService.queryByName(project, TYPE, packageName, null);\n\t\t\t\t\t\t\t\t\tvar distTags = new HashMap<String, String>();","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java#L131-L167","documentation":"NpmPackHandler.handle validates that the request path has at least one segment before dispatching. When the path is empty (pathSegments.isEmpty()) the handler cannot determine what npm registry operation was requested and throws ClientException with HTTP 400 Bad Request 'Invalid request path'.","triggerScenarios":"Calling the npm pack endpoint of a project with a path that normalizes to zero segments — e.g. requesting the pack base URL itself with no trailing route ('', '/' after split), via GET, PUT, or DELETE.","commonSituations":"npm clients pointed at the bare pack URL instead of the registry route; proxies or ingress rules stripping path prefixes; health checks hitting the pack endpoint root.","solutions":["Point the npm client at the full registry path including the route segments (e.g. /-/package/..., /v1/search, /<@scope>/pkg)","Check reverse proxy/ingress rewrite rules are not stripping required path prefixes","Verify how the project's pack URL is constructed in OneDev and include the operation path segment"],"exampleFix":"// before\nregistry = \"http://onedev.example.com/~projects/myproj/npm/\"\n// after\nregistry = \"http://onedev.example.com/~projects/myproj/npm/<route-path>\"","handlingStrategy":"validation","validationCode":"const route = new URL(packUrl).pathname.replace(/\\/+$/,'').split('/').filter(Boolean);\nif (route.length === 0) throw new Error('npm pack URL must include a route path, not just the base URL');","typeGuard":null,"tryCatchPattern":"try { await callNpmPack(url) } catch (e) { if (e.response?.status === 400 && /Invalid request path/i.test(e.message ?? '')) { console.error('Check registry URL and path routing'); } else throw e }","preventionTips":["Point clients at full registry routes, never the bare pack base URL","Verify reverse proxy rewrites preserve the full path","Add smoke tests hitting each supported npm route"],"tags":["http-400","npm","bad-request-path","pack-api"],"backgroundTag":"invalid-url-format","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}