can1357/oh-my-pi · error · ArchiveError
Invalid ARJ archive: truncated data
Error message
Invalid ARJ archive: truncated data
What it means
This ArchiveError is thrown when the number of bytes actually read from the ByteSource is less than the source's declared size — the archive data is truncated relative to what was promised. The library compares bytes.byteLength against source.size after fully reading.
Source
Thrown at packages/utils/src/ar/arj.ts:238
if (size < 30 || size > ARJ_MAX_BASIC_HEADER || bytes.byteLength < size + 8) return false;
const body = bytes.subarray(4, 4 + size);
return body[0]! >= 30 && body[0]! <= size && body[6] === 2 && crc32(body) === u32(bytes, 4 + size);
}
/** Index an ARJ archive and lazily decode stored, static-Huffman, and fast-LZSS members. */
export const readArj: FormatReader = async (
source: ByteSource,
options: FormatReadOptions,
): Promise<ArchiveIndexEntry[]> => {
assertInMemorySize(source.size, options.limits);
let bytes: Uint8Array;
try {
bytes = await readAllBytes(source);
} catch (error) {
if (error instanceof ArchiveError) throw error;
throw new ArchiveError(`Unable to read ARJ archive: ${error instanceof Error ? error.message : String(error)}`);
}
if (bytes.byteLength !== source.size) throw new ArchiveError("Invalid ARJ archive: truncated data");
if (!sniffArj(bytes)) throw new ArchiveError("Invalid ARJ archive header");
const main = parseArjBlock(bytes, 0, options);
if (main.isEnd) throw new ArchiveError("Invalid ARJ archive: missing main header");
const mainFirstHeaderSize = bytes[main.bodyStart]!;
if (mainFirstHeaderSize < 30 || mainFirstHeaderSize > main.bodySize || bytes[main.bodyStart + 6] !== 2) {
throw new ArchiveError("Invalid ARJ main header");
}
const mainFlags = bytes[main.bodyStart + 4]!;
if ((mainFlags & 0x01) !== 0) throw new ArchiveError("Encrypted ARJ archives are unsupported");
if ((mainFlags & 0x04) !== 0) throw new ArchiveError("Multi-volume ARJ archives are unsupported");
const entries: ArchiveIndexEntry[] = [];
let offset = main.nextOffset;
let metadataSize = main.metadataSize;
let parsedCount = 0;
for (;;) {
const block = parseArjBlock(bytes, offset, options);View on GitHub (pinned to 9690622007)
Solutions
- Re-download or re-copy the archive; the file is incomplete.
- Re-stat the file and pass a fresh, correct size to the ByteSource.
- Compare the on-disk file size to the expected size from the archive provider.
- If reading a stream, ensure the stream is fully drained and not closed early.
Example fix
// before
const stat = await fs.stat(path);
const entries = await readArj({ path, size: stat.size }, options);
// after
const stat = await fs.stat(path);
if (stat.size < expectedMinSize) throw new Error(`${path} looks truncated (${stat.size} bytes)`);
const entries = await readArj({ path, size: stat.size }, options); Defensive patterns
Strategy: validation
Validate before calling
const stat = await fs.stat(path);
if (stat.size === 0) throw new Error(`${path} is empty`);
// pass stat.size as the ByteSource size so the truncation check can fire accurately
const entries = await readArj({ path, size: stat.size }, options); Try / catch
try {
const entries = await readArj(source, options);
} catch (e) {
if (e instanceof ArchiveError && e.message.includes('truncated data')) {
throw new Error('archive is incomplete; re-download it');
}
throw e;
} Prevention
- Verify downloaded file size against the publisher's expected size
- Wait for downloads/copies to finish before parsing
- Pass an accurate source.size so the truncation invariant is meaningful
When it happens
Trigger: Calling readArj(source, options) where the underlying file/stream yields fewer bytes than source.size reported (file shrank between stat and read, partial download, reader stream ended early).
Common situations: Interrupted downloads, files still being written, rsync/copy interrupted, cloud-sync placeholders not fully materialized.
Related errors
- Unable to read ARJ archive: ${error instanceof Error ? error
- Invalid ARJ archive: truncated ${what}
- ARJ member '${memberPath}' has inconsistent stored size
- ARJ member '${memberPath}' has invalid no-data method sizes
- ARJ member '${memberPath}' uses unsupported compression meth
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1e4ec7d162db44e6.
Report an issue: GitHub.