theonedev/onedev · error · ClientException

Invalid request path

Error message

Invalid request path

What it means

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'.

Source

Thrown at server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java:149

	private byte[] decodeHex(String hexString) {
		try {
			return Hex.decodeHex(hexString);
		} catch (DecoderException e) {
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public void handle(HttpServletRequest request, HttpServletResponse response, Long projectId, 
						Long buildId, List<String> pathSegments) {
		var method = request.getMethod();
		
		var isGet = method.equals("GET");
		var isPut = method.equals("PUT");
		var isDelete = method.equals("DELETE");
		
		if (pathSegments.isEmpty())
			throw new ClientException(SC_BAD_REQUEST, "Invalid request path");
		
		var currentSegment = pathSegments.get(0);
		if (currentSegment.equals("-")) {
			pathSegments = pathSegments.subList(1, pathSegments.size());
			if (pathSegments.isEmpty())
				throw new ClientException(SC_BAD_REQUEST, "Invalid request path");				
			currentSegment = pathSegments.get(0);
			pathSegments = pathSegments.subList(1, pathSegments.size());
			if (currentSegment.equals("package")) {
				if (pathSegments.size() >= 2) {
					var packageName = decodePath(pathSegments.get(0));
					if (pathSegments.get(1).equals("dist-tags")) {
						if (pathSegments.size() == 2) {
							if (isGet) {
								sessionService.run(() -> {
									var project = checkProject(projectId, false);
									var packs = packService.queryByName(project, TYPE, packageName, null);
									var distTags = new HashMap<String, String>();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Point the npm client at the full registry path including the route segments (e.g. /-/package/..., /v1/search, /<@scope>/pkg)
  2. Check reverse proxy/ingress rewrite rules are not stripping required path prefixes
  3. Verify how the project's pack URL is constructed in OneDev and include the operation path segment

Example fix

// before
registry = "http://onedev.example.com/~projects/myproj/npm/"
// after
registry = "http://onedev.example.com/~projects/myproj/npm/<route-path>"
Defensive patterns

Strategy: validation

Validate before calling

const route = new URL(packUrl).pathname.replace(/\/+$/,'').split('/').filter(Boolean);
if (route.length === 0) throw new Error('npm pack URL must include a route path, not just the base URL');

Try / catch

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 }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/941a772d06488a25. Report an issue: GitHub.