can1357/oh-my-pi · error · ArchiveError
Archive is too large to read safely
Error message
Archive is too large to read safely
What it means
readRar() validates source.size before doing any work: it must be a non-negative safe integer. Otherwise the sparse-read strategy (which allocates based on size) would be unsafe, so it throws 'Archive is too large to read safely'.
Source
Thrown at packages/utils/src/ar/rar.ts:152
}
if (output.byteLength !== record.unpackedSize) corrupt(`member '${record.path}' size mismatch`);
if (record.crc !== undefined && crc32(output) !== record.crc) {
throw new ArchiveError(`RAR member '${record.path}' CRC32 mismatch`);
}
this.#cache.set(current, output.slice());
}
}
}
/** Probe the RAR 1.5-4.x or RAR5 signature. */
export function sniffRar(bytes: Uint8Array): boolean {
return findMarker(bytes) !== undefined;
}
/** Index a RAR4 or RAR5 archive and defer member decompression until extraction. */
export const readRar: FormatReader = async (source, options) => {
if (!Number.isSafeInteger(source.size) || source.size < 0) {
throw new ArchiveError("Archive is too large to read safely");
}
const indexed = await indexRarMetadata(source, options);
const bytes = sparseBytes(source.size, indexed.segments);
const marker = indexed.marker;
const records =
marker.version === 5 ? parseRar5(bytes, marker.offset, options) : parseRar4(bytes, marker.offset, options);
const archive = new RarArchive(source, records, options);
const entries: ArchiveIndexEntry[] = [];
for (let index = 0; index < records.length; index++) {
const record = records[index]!;
const entry: ArchiveIndexEntry = {
path: record.path,
isDirectory: record.isDirectory,
size: record.unpackedSize,
};
if (record.mtimeMs !== undefined) entry.mtimeMs = record.mtimeMs;
if (record.mode !== undefined) entry.mode = record.mode;
if (record.linkTarget !== undefined) {View on GitHub (pinned to 9690622007)
Solutions
- Ensure the Source has an accurate numeric size before calling readRar (stat the file and populate source.size)
- If the source is a stream of unknown length, buffer it to a file first and index from that
- Sanitize the size you report (0 <= size <= MAX_SAFE_INTEGER)
Example fix
// before
await readRar({ size: file.size ?? -1, read }, options);
// after
const stat = await fs.stat(path);
await readRar({ size: stat.size, read }, options); Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isSafeInteger(source.size) || source.size < 0) {
throw new Error('Source size must be a non-negative safe integer before calling readRar');
} Type guard
function hasValidSize(source: { size: unknown }): source is { size: number } {
return typeof source.size === 'number' && Number.isSafeInteger(source.size) && source.size >= 0;
} Try / catch
try {
const reader = await readRar(source, options);
} catch (err) {
if (err instanceof ArchiveError && err.message === 'Archive is too large to read safely') {
throw new Error('Provide a source with a known, non-negative integer size');
}
throw err;
} Prevention
- Stat files and populate source.size explicitly; never pass undefined/-1 placeholders
- For streams of unknown length, spill to a temp file and index from the file
- Coerce sizes from 32-bit APIs carefully (negative overflow) before constructing the Source
When it happens
Trigger: Calling readRar(source, options) where source.size is undefined, negative, fractional, or exceeds Number.MAX_SAFE_INTEGER — e.g. a Blob/File with unknown size, a streaming source reporting -1, or a bogus stat.
Common situations: Passing a handle to a pipe/device whose size is unknown; using a custom Source implementation that doesn't populate size; 32-bit overflow artifacts in metadata.
Related errors
- Invalid compress (.Z) header
- Invalid compress (.Z) maximum code width ${maxBits}
- Unsupported RAR4 compression algorithm version ${version}
- Unsupported RAR4 PPMd compressed block
- Unsupported RAR4 RarVM filter type ${type || "unknown"}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f0e87dc37ded73ae.
Report an issue: GitHub.