theonedev/onedev · error · ClientException

Missing version or file name

Error message

Missing version or file name

What it means

Thrown when an npm client sends a request whose path contains the '-' segment (the tarball download/publish path segment) but provides no further path segments, so OneDev cannot determine the requested version or file name. The server rejects it with HTTP 400.

Source

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

								var project = checkProject(projectId, true);
								var packs = packService.queryByName(project, TYPE, packageName, null);
								if (!packs.isEmpty()) {
									for (var pack: packs)
										packService.delete(pack);
									response.setStatus(SC_OK);									
								} else {
									response.setStatus(SC_NOT_FOUND);
								}
							});
						});
					} else if (isPut) {
						response.setStatus(SC_OK);						
					} else {
						throw new ClientException(SC_METHOD_NOT_ALLOWED);
					}
				} else if (currentSegment.equals("-")) {
					if (pathSegments.isEmpty())
						throw new ClientException(SC_BAD_REQUEST, "Missing version or file name");
					pathSegments = pathSegments.subList(1, pathSegments.size());
					if (pathSegments.size() == 1) {
						var fileName = decodePath(pathSegments.get(0));
						if (fileName.startsWith(packageName + "-")) {
							var version = substringBefore(fileName.substring(packageName.length() + 1), ".");
							sessionService.run(() -> {
								var project = checkProject(projectId, false);
								var pack = packService.findByNameAndVersion(project, TYPE, packageName, version);
								if (pack != null) {
									var packData = (NpmData) pack.getData();
									PackBlob packBlob;
									if ((packBlob = packBlobService.checkPackBlob(projectId, packData.getFileSha256BlobHash())) != null) {
										try {
											response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
											packBlobService.downloadBlob(packBlob.getProject().getId(), packBlob.getSha256Hash(), response.getOutputStream());
											response.setStatus(SC_OK);
										} catch (IOException e) {
											throw new RuntimeException(e);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Include the full tarball file name after the '-' segment: GET /npm/<project>/<scope>/<name>/-/<name>-<version>.tgz.
  2. Check the package metadata dist.tarball URL the client is using and ensure it is complete and points at the OneDev registry.
  3. If using a custom client or script, fix the URL construction to append the tarball name.

Example fix

// before
curl https://onedev.example.com/npm/proj/my-pkg/-
// after
curl -O https://onedev.example.com/npm/proj/my-pkg/-/my-pkg-1.0.0.tgz
Defensive patterns

Strategy: validation

Validate before calling

// Validate the tarball URL has a file segment after '-'
const u = new URL(pkg.dist.tarball);
const parts = u.pathname.split('/');
const dashIdx = parts.indexOf('-');
if (dashIdx === -1 || dashIdx === parts.length - 1) throw new Error('Tarball URL missing file name after - segment');

Prevention

When it happens

Trigger: Request path ending at .../<packageName>/-/ with nothing after the dash segment; the code checks pathSegments.isEmpty() immediately after matching currentSegment.equals("-").

Common situations: Misconfigured npm registry URL missing the tarball filename (e.g. dist.tarball truncated); hand-written HTTP requests or curl scripts omitting the file part of the path; broken npm client versions building malformed tarball URLs.

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/df33e04af49271c1. Report an issue: GitHub.