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
- Regenerate the publish payload with a standard npm client instead of hand-crafting JSON
- Ensure the 'length' field equals the byte length of the decoded 'data' for every attachment
- Check any intermediate proxy/pipeline for payload truncation or transformation
- 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
- Let standard npm clients build publish payloads
- Never transform or truncate base64 bodies in transit
- Validate _attachments locally before publishing in custom scripts
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
- Integrity check failed:
- Invalid request path
- Package metadata exceeds maximum size:
- Package already exists (name: %s, version: %s)
- Unexpected integrity algorithm (file: %s, algorithm: %s)
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/6ccacbf989d78a76.
Report an issue: GitHub.