theonedev/onedev · error · ClientException

File length incorrect:

Error message

File length incorrect: 

What it means

npm publish metadata contains an _attachments object where each attachment declares its content (base64 'data') and a 'length' field. The handler decodes the base64 data and compares the decoded byte length to the declared length; a mismatch throws ClientException HTTP 400 'File length incorrect: <fileName>'.

Source

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

						var distTags = new HashMap<String, String>();
						var distTagsNode = packageMetadata.get("dist-tags");
						if (distTagsNode != null) {
							for (var it = distTagsNode.fields(); it.hasNext(); ) {
								var field = it.next();
								distTags.put(field.getKey(), field.getValue().asText());
							}
						}

						var attachments = new HashMap<String, byte[]>();
						var attachmentsNode = packageMetadata.get("_attachments");
						if (attachmentsNode != null) {
							for (var it = attachmentsNode.fields(); it.hasNext(); ) {
								var field = it.next();
								var fileName = field.getKey();
								var fileContent = Base64.decodeBase64(field.getValue().get("data").asText());
								if (fileContent.length != field.getValue().get("length").asInt()) {
									throw new ClientException(SC_BAD_REQUEST, "File length incorrect: " + fileName);
								}
								attachments.put(fileName, fileContent);
							}
						}

						var versionsNode = packageMetadata.get("versions");

						packageMetadata.remove("dist-tags");
						packageMetadata.remove("versions");
						packageMetadata.remove("_attachments");
						packageMetadata.remove("access");

						byte[] packageMetadataBytes = writeJson(packageMetadata);

						if (versionsNode != null) {
							for (var it = versionsNode.fields(); it.hasNext(); ) {
								var field = it.next();
								var version = field.getKey();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Regenerate the publish payload with a standard npm client instead of hand-crafting JSON
  2. Ensure the 'length' field equals the byte length of the decoded 'data' for every attachment
  3. Check any intermediate proxy/pipeline for payload truncation or transformation
  4. Verify the file wasn't modified after length was computed (re-run npm publish)

Example fix

// before
"length": 1024,
"data": "<base64 of 2048-byte tarball>"
// after
"length": 2048,
"data": "<base64 of 2048-byte tarball>"
Defensive patterns

Strategy: validation

Validate before calling

for (const [name, att] of Object.entries(meta._attachments)) {
  const bytes = Buffer.from(att.data, 'base64');
  if (bytes.length !== att.length) throw new Error(`Attachment ${name} length mismatch: ${bytes.length} != ${att.length}`);
}

Type guard

function hasConsistentAttachment(att) {
  return typeof att?.data === 'string' && typeof att?.length === 'number'
    && Buffer.from(att.data, 'base64').length === att.length;
}

Try / catch

try { await publish() } catch (e) { if (e.response?.status === 400 && /File length incorrect/i.test(e.message ?? '')) { console.error('Attachment length field does not match decoded data'); } else throw e }

Prevention

When it happens

Trigger: Publishing with metadata where an attachment's 'length' field does not equal the byte length of its base64-decoded 'data' — corrupted metadata generation, manual construction of publish payloads, or truncation in transit/transform.

Common situations: Custom publish scripts hand-building the npm publish document; proxies modifying/truncating base64 payloads; libraries generating attachments with wrong length fields; encoding issues (e.g. re-encoding data as base64 twice).

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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