can1357/oh-my-pi · error · ArchiveError
Invalid RAR archive: ${reason}
Error message
Invalid RAR archive: ${reason} What it means
Generic corruption guard for RAR archives: `corrupt(reason)` throws ArchiveError("Invalid RAR archive: <reason>") whenever structural parsing assumptions fail — bad signatures, truncated headers, out-of-bounds offsets, missing mandatory headers (e.g. 'RAR4 main header is missing'). The interpolated `reason` names the specific structural problem found (packages/utils/src/ar/rar.ts:734).
Source
Thrown at packages/utils/src/ar/rar.ts:734
function filetimeMs(bytes: Uint8Array, offset: number): number {
const ticks = readUInt32LE(bytes, offset) + readUInt32LE(bytes, offset + 4) * 0x100000000;
return ticks / 10000 - 11644473600000;
}
function checkedEnd(start: number, size: number, limit: number, what: string): number {
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(size) || size < 0) corrupt(`invalid ${what} range`);
const end = start + size;
if (!Number.isSafeInteger(end) || end < start || end > limit) corrupt(`truncated ${what}`);
return end;
}
function need(start: number, size: number, end: number, what: string): void {
checkedEnd(start, size, end, what);
}
function corrupt(reason: string): never {
throw new ArchiveError(`Invalid RAR archive: ${reason}`);
}
View on GitHub (pinned to 9690622007)
Solutions
- Re-download or re-copy the archive and verify its checksum/hash matches the source.
- Validate the archive externally (`unrar t archive.rar` or `7z t archive.rar`) to confirm it opens elsewhere; if it doesn't, the file is corrupt, not a library issue.
- Confirm the file is actually a RAR (magic bytes: Rar!\x1a\x07 for RAR4/RAR5) and wasn't renamed from another format.
- Check transfer mode — re-transfer over binary mode (FTP binary, no text transformations).
- Catch ArchiveError, inspect the `reason` suffix, and surface it to the user so they can repair/re-obtain the archive.
Example fix
// before: trusting an unverified download
const reader = await openArchive(archivePath);
// after: verify integrity before parsing
const ok = await $`7z t ${archivePath}`.quiet().nothrow();
if (ok.exitCode !== 0) throw new Error(`${archivePath} failed integrity check; re-download it`);
const reader = await openArchive(archivePath); Defensive patterns
Strategy: try-catch
Validate before calling
// Verify magic bytes + transfer integrity before parsing
const sig = new Uint8Array(await Bun.file(p).slice(0, 7).arrayBuffer());
const validSig = sig[0] === 0x52 && sig[1] === 0x61 && sig[2] === 0x72 && sig[3] === 0x21 && sig[4] === 0x1a && sig[5] === 0x07;
if (!validSig) throw new Error(`${p} is not a RAR archive (bad signature)`);
// optionally: const t = await $`unrar t ${p}`.quiet().nothrow(); if (t.exitCode !== 0) throw ... Type guard
function isRarMagic(bytes: Uint8Array): boolean {
return bytes.length >= 6 &&
bytes[0] === 0x52 && bytes[1] === 0x61 && bytes[2] === 0x72 &&
bytes[3] === 0x21 && bytes[4] === 0x1a && bytes[5] === 0x07;
} Try / catch
try {
const reader = await openArchive(p);
return reader;
} catch (err) {
if (err instanceof ArchiveError && err.message.startsWith('Invalid RAR archive:')) {
throw new Error(`${p} is corrupt (${err.message}); re-download and verify its checksum`);
}
throw err;
} Prevention
- Verify checksums/hashes after every download before parsing.
- Check the Rar! magic bytes before opening.
- Use binary-safe transfer (no text-mode FTP/ASCII conversion).
- Run `unrar t` / `7z t` as a pre-flight integrity gate in pipelines.
When it happens
Trigger: Any call that parses RAR data (listing, reading entries) when the byte stream violates RAR structure: truncated download, flipped/invalid signature bytes, offsets running past buffer end via `need()`/`checkedEnd()`, missing RAR4 main header, or malformed header fields.
Common situations: Incomplete HTTP download or interrupted transfer; archive corrupted in storage/transit; someone renamed a non-RAR file to .rar; text-mode (FTP/ASCII) transfer mangling binary data; edited or partially deleted archive file.
Related errors
- RAR member '${record.path}' CRC32 mismatch
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
- ARJ member '${memberPath}' has inconsistent stored size
- ARJ member '${memberPath}' has invalid no-data method sizes
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1b6c2d2b7b23e878.
Report an issue: GitHub.