can1357/oh-my-pi · error · ArchiveError
Invalid tar numeric field
Error message
Invalid tar numeric field
What it means
readTarNumeric decodes tar header numeric fields (octal text or GNU base-256 binary) from the archive buffer. This throw means the requested field does not fit inside the buffer at all (negative offset, non-positive length, or offset+length past the end of the bytes). The library throws instead of reading out-of-bounds because the header block is truncated or the caller supplied a bad offset.
Source
Thrown at packages/utils/src/ar/tar.ts:115
bytesMatchAscii(buffer, offset + MAGIC_OFFSET, MAGIC) && bytesMatchAscii(buffer, offset + VERSION_OFFSET, VERSION)
);
}
function readMetadataPath(data: Uint8Array, field: string, limits: ArchiveLimits): string {
const nul = data.indexOf(0);
const value = data.subarray(0, nul === -1 ? data.byteLength : nul);
assertArchivePathBytes(value.byteLength, field, limits.maxPathBytes);
return TEXT_DECODER.decode(value);
}
function readPaxPath(data: Uint8Array, field: string, limits: ArchiveLimits): string {
assertArchivePathBytes(data.byteLength, field, limits.maxPathBytes);
return TEXT_DECODER.decode(data);
}
function readTarNumeric(buffer: Uint8Array, offset: number, length: number): number {
if (offset < 0 || length <= 0 || offset + length > buffer.byteLength) {
throw new ArchiveError("Invalid tar numeric field");
}
const first = buffer[offset]!;
let value = 0n;
if ((first & 0x80) !== 0) {
value = BigInt(first & 0x7f);
for (let index = 1; index < length; index++) {
value = (value << 8n) | BigInt(buffer[offset + index]!);
}
if ((first & 0x40) !== 0) value -= 1n << BigInt(length * 8 - 1);
} else {
for (let index = 0; index < length; index++) {
const byte = buffer[offset + index]!;
if (byte >= 0x30 && byte <= 0x37) value = value * 8n + BigInt(byte - 0x30);
}
}
return Number(value);
}
View on GitHub (pinned to 9690622007)
Solutions
- Verify the input is a complete tar buffer (at least one 512-byte block) before parsing; use sniffTar to detect the format first.
- Check where the offset/length arguments come from — an earlier miscomputed size or offset in your own code is the usual culprit.
- Re-download or re-extract the archive; a truncated file cannot be repaired by the parser.
- Wrap the parse in try-catch on ArchiveError and surface 'corrupt/truncated tar archive' to the user.
Example fix
// before
const size = readTarNumeric(truncatedChunk, 124, 12); // throws
// after
if (truncatedChunk.byteLength < 512) throw new Error("tar buffer too small");
const size = readTarNumeric(truncatedChunk, 124, 12); Defensive patterns
Strategy: validation
Validate before calling
import { sniffTar } from "@oh-my-pi/pi-utils/ar/tar";
if (buffer.byteLength < 512 || !sniffTar(buffer)) {
throw new Error("Input is not a complete tar archive");
} Try / catch
try {
const entries = readTarEntriesFromBuffer(buffer, options);
} catch (err) {
if (err instanceof ArchiveError && err.message === "Invalid tar numeric field") {
throw new Error("Tar buffer truncated or misaligned: header field out of bounds");
}
throw err;
} Prevention
- Always pass whole, complete tar buffers — never partial reads — to the tar readers.
- Run sniffTar before parsing untrusted bytes.
- Double-check offsets if you slice headers yourself; tar headers are fixed 512-byte blocks.
- Validate downloads against a checksum before extraction.
When it happens
Trigger: Calling readTarNumeric (via the size/stored/mtime/rawMode accessors of a tar member) on a buffer shorter than the field requires — e.g. a buffer < 512 bytes passed where a full tar header block is expected, or an offset computed past buffer end.
Common situations: Feeding a truncated download (partial tar), a buffer sliced at the wrong offset, sniffing a file smaller than one 512-byte block, or passing non-tar bytes to a helper that trusts a size field.
Related errors
- Archive member '${formatArchivePathForError(memberPath)}' ha
- Invalid tar member size
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
- Unsafe embedded addon archive entry: ${filename}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5c4540cbab0ef635.
Report an issue: GitHub.