can1357/oh-my-pi · error · ArchiveError
Invalid tar PAX record
Error message
Invalid tar PAX record
What it means
parsePaxRecords splits PAX extended-header data into '<length> <key>=<value>\n' records. This throw fires while reading the leading length token: there is no space after a non-empty token, the token is longer than 16 digits, or the record starts with a space. A well-formed PAX blob always begins each record with a decimal length followed by a space.
Source
Thrown at packages/utils/src/ar/tar.ts:182
let signed = 0;
for (let index = 0; index < BLOCK_SIZE; index++) {
const inChecksum = index >= CHECKSUM_OFFSET && index < CHECKSUM_OFFSET + CHECKSUM_LENGTH;
const byte = inChecksum ? 0x20 : (buffer[offset + index] ?? 0);
unsigned += byte;
signed += (byte << 24) >> 24;
}
return stored === unsigned || stored === signed;
}
function parsePaxRecords(data: Uint8Array, limits: ArchiveLimits): Map<string, string> {
assertIndexSize(data.byteLength, limits, "tar PAX metadata");
const attrs = new Map<string, string>();
let pos = 0;
while (pos < data.byteLength) {
let space = pos;
while (space < data.byteLength && data[space] !== 0x20) space++;
if (space === pos || space >= data.byteLength || space - pos > 16) {
throw new ArchiveError("Invalid tar PAX record");
}
let length = 0;
for (let index = pos; index < space; index++) {
const byte = data[index]!;
if (byte < 0x30 || byte > 0x39) throw new ArchiveError("Invalid tar PAX record");
length = length * 10 + (byte - 0x30);
if (length > data.byteLength - pos) throw new ArchiveError("Invalid tar PAX record");
}
if (length <= 0 || pos + length > data.byteLength || data[pos + length - 1] !== 0x0a) {
throw new ArchiveError("Invalid tar PAX record");
}
const record = data.subarray(space + 1, pos + length - 1);
const equals = record.indexOf(0x3d);
if (equals >= 0) {
const key = record.subarray(0, equals);
const value = record.subarray(equals + 1);
if (bytesMatchAscii(key, 0, PAX_SPARSE_MARKER)) {
attrs.set(PAX_SPARSE_MARKER, value.byteLength === 0 ? "" : "1");View on GitHub (pinned to 9690622007)
Solutions
- Verify archive integrity — this error usually means the PAX member bytes are corrupt or misaligned.
- Check the preceding header's size field: a wrong size there shifts data alignment and breaks PAX parsing.
- Regenerate the archive with GNU tar/bsdtar if a custom writer emitted it.
- Catch ArchiveError and reject the archive; PAX records cannot be partially recovered.
Defensive patterns
Strategy: try-catch
Validate before calling
// PAX payload must start with '<digits> ' per record
function looksLikePaxPayload(data: Uint8Array): boolean {
const first = data[0];
if (first === undefined || first === 0x20) return false; // empty/leading-space length
return first >= 0x30 && first <= 0x39;
} Try / catch
try {
const entries = readTarEntriesFromBuffer(buffer, options);
} catch (err) {
if (err instanceof ArchiveError && err.message === "Invalid tar PAX record") {
throw new Error("PAX extended header payload is malformed or misaligned");
}
throw err;
} Prevention
- Verify archives with a reference tool (tar -tvf) before programmatic parsing.
- Keep the format module's limits intact — truncated PAX payloads usually stem from earlier corruption.
- Regenerate archives with standard tooling rather than hand-patching bytes.
- If you write PAX headers, include the length prefix and space in the record length.
When it happens
Trigger: Typeflag 'x'/'g' member whose payload does not start with `<digits> ` — e.g. payload begins with '=' (empty length), or a run of >16 non-space bytes — encountered while indexing via readTar/readTarEntriesFromBuffer.
Common situations: Corrupted archives, archives where PAX payload was truncated or shifted by an earlier bad size, or bytes that are not really PAX data being interpreted as such because a header typeflag was damaged.
Related errors
- Invalid tar ${field}
- 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/c115de2b60e42c16.
Report an issue: GitHub.