can1357/oh-my-pi · error · ArchiveError
Tar numeric value does not fit its header field
Error message
Tar numeric value does not fit its header field
What it means
While encoding a tar header, a numeric field (size, mtime, mode, uid/gid) is written as zero-padded ASCII octal into a fixed-width header field. The library throws this when the value's octal representation has more digits than the field can hold (length-1 digits plus terminator). This prevents silently writing a truncated/corrupt tar header.
Source
Thrown at packages/utils/src/ar/tar.ts:613
if (isZeroBlock(bytes, 0)) return true;
try {
if (readTarString(bytes, NAME_OFFSET, NAME_LENGTH).length === 0) return false;
const size = readTarSize(bytes, SIZE_OFFSET);
return Number.isSafeInteger(paddedSize(size)) && checksumMatches(bytes, 0);
} catch {
return false;
}
}
function writeField(target: Uint8Array, offset: number, length: number, value: Uint8Array): void {
if (value.byteLength > length) throw new ArchiveError("Tar header field is too long");
target.set(value, offset);
}
function writeOctal(target: Uint8Array, offset: number, length: number, value: number): void {
if (!Number.isSafeInteger(value) || value < 0) throw new ArchiveError("Invalid tar numeric value");
const digits = value.toString(8);
if (digits.length > length - 1) throw new ArchiveError("Tar numeric value does not fit its header field");
for (let index = offset; index < offset + length - 1 - digits.length; index++) target[index] = 0x30;
for (let index = 0; index < digits.length; index++)
target[offset + length - 1 - digits.length + index] = digits.charCodeAt(index);
target[offset + length - 1] = 0;
}
function splitUstarPath(pathBytes: Uint8Array): readonly [Uint8Array, Uint8Array] | undefined {
if (pathBytes.byteLength <= NAME_LENGTH) return [pathBytes, new Uint8Array(0)];
for (let index = pathBytes.byteLength - 1; index > 0; index--) {
if (pathBytes[index] !== 0x2f) continue;
const prefix = pathBytes.subarray(0, index);
const name = pathBytes.subarray(index + 1);
if (prefix.byteLength <= PREFIX_LENGTH && name.byteLength > 0 && name.byteLength <= NAME_LENGTH) {
return [name, prefix];
}
}
return undefined;
}View on GitHub (pinned to 9690622007)
Solutions
- Reduce member sizes below 8 GB or split large files before archiving
- Pass mtime in seconds, not milliseconds (Math.floor(ms / 1000))
- Verify size/mode/uid/gid values are the ustar-encoded numeric range expected
- Switch to an archive format without the ustar size limit (zip, or a tar writer with PAX/GNU extensions)
Example fix
// before
appendTarEntry(parts, path, hugeFileBytes, false, 0, { mtime: Date.now() });
// after
appendTarEntry(parts, path, hugeFileBytes, false, 0, { mtime: Math.floor(Date.now() / 1000) }); Defensive patterns
Strategy: validation
Validate before calling
const USTAR_SIZE_LIMIT = 0o77777777777; // 8 GB - 1
if (bytes.byteLength > USTAR_SIZE_LIMIT) {
throw new Error(`Member '${path}' exceeds ustar size field (${bytes.byteLength} bytes)`);
}
const mtimeSec = Math.floor(mtimeMs / 1000);
if (!Number.isSafeInteger(mtimeSec) || mtimeSec < 0 || mtimeSec > 0o7777777777) {
throw new Error(`mtime ${mtimeMs} out of ustar range`);
} Try / catch
try {
const tar = await createTar(members);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("does not fit its header field")) {
// split oversized members or use a different format
}
throw err;
} Prevention
- Always pass mtime in seconds, never Date.now() directly
- Check member sizes against the 8 GB ustar limit before encoding
- Prefer zip or PAX tar for archives that may exceed ustar limits
When it happens
Trigger: Calling createTar (or appendTarEntry) with a file whose size exceeds the ustar size field limit (8 GB, since octal 77777777777 = 8589934591 bytes), an mtime beyond ~Oct 2242, or a uid/gid/mode too large for its field width.
Common situations: Archiving files larger than 8 GB with the ustar (not GNU/PAX) format; passing a Date.now()-in-milliseconds mtime instead of seconds; a corrupted or bogus size from a custom metadata source.
Related errors
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
- Unsafe embedded addon archive entry: ${filename}
- Unsupported embedded addon archive entry type ${typeflag}: $
- Invalid ARJ ${field}: missing terminator
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/9d01663a03702a62.
Report an issue: GitHub.