can1357/oh-my-pi · error · ArchiveError
Archive member '${formatArchivePathForError(memberPath)}' is
Error message
Archive member '${formatArchivePathForError(memberPath)}' is truncated What it means
TarMemberSource.read() checks that the requested size does not extend past the end of the in-memory tar buffer relative to the member's data offset. This throw means the tar header declared a member larger than the actual bytes remaining in the archive — the archive is truncated or corrupted. It fires before slicing, so no short data is ever silently returned.
Source
Thrown at packages/utils/src/ar/tar.ts:74
class TarMemberSource implements MemberSource {
readonly #buffer: Uint8Array;
readonly #dataOffset: number;
readonly #sparse: boolean;
constructor(buffer: Uint8Array, dataOffset: number, sparse: boolean) {
this.#buffer = buffer;
this.#dataOffset = dataOffset;
this.#sparse = sparse;
}
async read(size: number, memberPath: string): Promise<Uint8Array> {
if (this.#sparse) {
throw new ArchiveError(
`Archive member '${formatArchivePathForError(memberPath)}' is a sparse file and cannot be read`,
);
}
if (size > this.#buffer.byteLength - this.#dataOffset) {
throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' is truncated`);
}
const bytes = this.#buffer.subarray(this.#dataOffset, this.#dataOffset + size);
if (bytes.byteLength !== size) {
throw new ArchiveError(`Archive member '${formatArchivePathForError(memberPath)}' has an invalid size`);
}
return bytes;
}
}
function readTarString(buffer: Uint8Array, offset: number, length: number): string {
const limit = Math.min(offset + length, buffer.byteLength);
let end = offset;
while (end < limit && buffer[end] !== 0) end++;
return TEXT_DECODER.decode(buffer.subarray(offset, end));
}
function bytesEqualAscii(bytes: Uint8Array, value: string): boolean {
return bytes.byteLength === value.length && bytesMatchAscii(bytes, 0, value);View on GitHub (pinned to 9690622007)
Solutions
- Re-obtain the archive (re-download/re-copy) and verify its size/checksum against the source manifest
- Validate the whole tar by walking all headers before extraction to catch truncation early
- Check the tar size field for corruption if the file size matches expectations but reads still fail
- Surface a user-facing 'archive is incomplete' message instead of retrying reads against a truncated buffer
Example fix
// before: extracting without integrity check
const reader = await readTar(await readAllBytes(src));
await extractAll(reader);
// after: verify total size against manifest before parsing
if (bytes.byteLength !== manifest["bundle.tar"].size) {
throw new Error("tar truncated; re-download");
}
const reader = await readTar(bytes); Defensive patterns
Strategy: validation
Validate before calling
const stat = await fs.stat(path);
if (manifest[archiveName] && stat.size !== manifest[archiveName].size) {
throw new Error(`tar truncated on disk (${stat.size} != ${manifest[archiveName].size}); re-download`);
} Try / catch
try {
const data = await entry.source.read(entry.size, entry.path);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("is truncated")) {
throw new Error(`tar is incomplete; member ${entry.path} extends past end of file — re-obtain the archive`, { cause: err });
}
throw err;
} Prevention
- Verify download completeness (size + checksum) before parsing a tar
- Walk all tar headers at open time to validate the archive before extracting members
- Avoid rsync/scp/concat operations that can silently truncate archives
- Treat this error as data corruption: never retry the read; re-obtain the file
When it happens
Trigger: Reading a tar member whose header size field exceeds buffer.byteLength - dataOffset: the archive download/copy was cut short, the file was truncated at rest, or a corrupt size field (bad octal/PAX size) in the header inflates the declared size.
Common situations: Interrupted downloads or scp/rsync transfers; tar files concatenated or edited incorrectly; archives stored on failing disks; sizes corrupted by a writer bug (non-terminated octal fields) making a member appear larger than the file.
Related errors
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
- CPIO member '${memberPath}' is truncated
- Archive member '${formatArchivePathForError(memberPath)}' ha
- Archive member data is truncated
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/607edf3d8813f830.
Report an issue: GitHub.