can1357/oh-my-pi · error · ArchiveError
Invalid tar ${field}
Error message
Invalid tar ${field} What it means
parsePaxSize parses a size string taken from a PAX extended-header record ('size', 'GNU.sparse.realsize', etc.). This throw fires when the string is not pure decimal digits — the field name is interpolated into the message, e.g. "Invalid tar member size" or "Invalid tar sparse real size". PAX stores large values as decimal text, so any non-digit means the record is malformed.
Source
Thrown at packages/utils/src/ar/tar.ts:148
}
return Number(value);
}
function readTarSize(buffer: Uint8Array, offset: number): number {
const size = readTarNumeric(buffer, offset, SIZE_LENGTH);
if (!Number.isSafeInteger(size) || size < 0) throw new ArchiveError("Invalid tar member size");
return size;
}
function paddedSize(size: number): number {
const remainder = size % BLOCK_SIZE;
const padded = size + (remainder === 0 ? 0 : BLOCK_SIZE - remainder);
if (!Number.isSafeInteger(padded)) throw new ArchiveError("Invalid tar member size");
return padded;
}
function parsePaxSize(value: string, field: string): number {
if (!/^\d+$/.test(value)) throw new ArchiveError(`Invalid tar ${field}`);
const size = Number(value);
if (!Number.isSafeInteger(size) || size < 0) throw new ArchiveError(`Invalid tar ${field}`);
return size;
}
function isZeroBlock(buffer: Uint8Array, offset: number): boolean {
for (let index = 0; index < BLOCK_SIZE; index++) {
if (buffer[offset + index] !== 0) return false;
}
return true;
}
function checksumMatches(buffer: Uint8Array, offset: number): boolean {
const stored = readTarNumeric(buffer, offset + CHECKSUM_OFFSET, CHECKSUM_LENGTH);
let unsigned = 0;
let signed = 0;
for (let index = 0; index < BLOCK_SIZE; index++) {
const inChecksum = index >= CHECKSUM_OFFSET && index < CHECKSUM_OFFSET + CHECKSUM_LENGTH;View on GitHub (pinned to 9690622007)
Solutions
- Inspect the PAX record in the archive (tar --to-stdout on the PaxHeaders member) and fix or regenerate the archive.
- Ensure the tool that wrote the archive emits PAX numeric values as plain decimal ASCII digits.
- Recreate the archive with a standard tar implementation (GNU tar, bsdtar) if a custom writer produced it.
- Catch ArchiveError and reject the archive; the parser will not guess at malformed numerics.
Example fix
// before (custom PAX writer)
record = `size=0x${size.toString(16)}\n`;
// after
record = `size=${size.toString(10)}\n`; Defensive patterns
Strategy: try-catch
Validate before calling
// PAX numeric records must be pure decimal ASCII digits
function isValidPaxNumber(value: string): boolean {
return /^\d+$/.test(value);
} Try / catch
try {
const entries = readTarEntriesFromBuffer(buffer, options);
} catch (err) {
if (err instanceof ArchiveError && err.message.startsWith("Invalid tar ")) {
throw new Error(`Archive has a malformed PAX numeric record (${err.message})`);
}
throw err;
} Prevention
- Write PAX numeric values as plain decimal strings only (no hex, suffixes, or whitespace).
- Test custom tar writers against GNU tar/bsdtar round-trips.
- Inspect PaxHeaders members with a reference tool when debugging malformed archives.
- Reject archives that fail standard tar validation before indexing.
When it happens
Trigger: A PAX extended header (typeflag 'x'/'g') contains a size-ish record whose value has non-digit characters — e.g. `size=12abc\n` or an empty/whitespace value — parsed during readTarEntriesFromBuffer.
Common situations: Archives written by non-conforming tools, hand-edited or corrupted PAX headers, or a writer that put a formatted (hex, suffixed) number into a PAX record.
Related errors
- Invalid tar PAX record
- Invalid tar sparse real size
- Archive member '${formatArchivePathForError(name)}' is trunc
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/10e4156183b2cde1.
Report an issue: GitHub.