can1357/oh-my-pi · error · ArchiveError
RAR5 dictionary is too large (${dictionarySize} bytes)
Error message
RAR5 dictionary is too large (${dictionarySize} bytes) What it means
Each RAR5 compressed member declares a LZ dictionary size derived from the compression-info bits (128 KiB * 2^power, optionally extended). If the computed dictionary is not a safe integer or exceeds options.limits.maxInMemorySize, the library refuses because members are decompressed in memory.
Source
Thrown at packages/utils/src/ar/rar.ts:365
mtimeMs = readUInt32LE(bytes, cursor.offset) * 1000;
cursor.offset += 4;
}
let dataCrc: number | undefined;
if ((fileFlags & 4) !== 0) {
need(cursor.offset, 4, extraStart, "RAR5 data CRC32");
dataCrc = readUInt32LE(bytes, cursor.offset);
cursor.offset += 4;
}
const compression = readVint(bytes, cursor, extraStart, "compression information");
let version = compression & 0x3f;
if (version === 1 && (compression & 0x100000) !== 0) version = 0;
const solid = (compression & 0x40) !== 0;
const method = (compression >>> 7) & 7;
const dictionaryPower = (compression >>> 10) & 0x1f;
let dictionarySize = 128 * 1024 * 2 ** dictionaryPower;
if ((compression & 0x3f) === 1) dictionarySize += (dictionarySize * ((compression >>> 15) & 0x1f)) / 32;
if (!Number.isSafeInteger(dictionarySize) || dictionarySize > options.limits.maxInMemorySize) {
throw new ArchiveError(`RAR5 dictionary is too large (${dictionarySize} bytes)`);
}
const hostOs = readVint(bytes, cursor, extraStart, "host OS");
const nameSize = readVint(bytes, cursor, extraStart, "file name size");
assertArchivePathBytes(nameSize, "member path", options.limits.maxPathBytes);
need(cursor.offset, nameSize, extraStart, "RAR5 file name");
let rawPath: string;
try {
rawPath = UTF8.decode(bytes.subarray(cursor.offset, cursor.offset + nameSize));
} catch {
throw new ArchiveError("Invalid RAR5 UTF-8 member name");
}
cursor.offset += nameSize;
let linkTarget: string | undefined;
for (const extra of readExtraRecords(bytes, extraStart, headerEnd)) {
const extraCursor = { offset: extra.start };
if (extra.type === 1) throw new ArchiveError(`Encrypted RAR5 member '${rawPath}' is not supported`);
if (extra.type === 3) {
const timeFlags = readVint(bytes, extraCursor, extra.end, "time flags");View on GitHub (pinned to 9690622007)
Solutions
- Raise options.limits.maxInMemorySize when the archive is trusted and the dictionary size is acceptable
- Re-compress the archive with a smaller dictionary (`rar -md<m>` default is small)
- Reject such archives upstream and fall back to the unrar CLI
Example fix
// before
const records = readRar(bytes, { limits: { maxInMemorySize: 64 * 1024 * 1024 } });
// after
const records = readRar(bytes, { limits: { maxInMemorySize: 1024 * 1024 * 1024 } }); // allow 1GiB dictionaries Defensive patterns
Strategy: validation
Validate before calling
// raise the in-memory cap if trusted archives use big dictionaries
const options = { limits: { maxInMemorySize: 512 * 1024 * 1024 } }; Try / catch
try {
const records = readRar(bytes, options);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('dictionary is too large')) {
const m = /\((\d+) bytes\)/.exec(err.message);
// surface required size to caller, or re-compress externally
} else throw err;
} Prevention
- Set maxInMemorySize generously on trusted inputs, tightly on untrusted ones
- Avoid very large -md dictionary settings when targeting parsers
- Document the memory cap for consumers of your service
When it happens
Trigger: Reading a RAR5 member compressed with a very large dictionary (dictionaryPower near 0x1f, i.e. dictionaries of gigabytes) while options.limits.maxInMemorySize is smaller than that dictionary.
Common situations: Users maximizing compression ratio with `rar -md1g` or larger on huge inputs; archives created with modern WinRAR 7 64-bit dictionary sizes parsed by a library configured with a small memory cap; strict maxInMemorySize set for safety in server environments.
Related errors
- Summary exceeds ${config.summaryHardLimit} bytes
- ${name} exceeds the ${SHARPSHOOTER_MAX_FILE_LINES}-line limi
- xAI image edits accept up to ${XAI_MAX_EDIT_IMAGES} referenc
- response exceeds ${maxBytes} bytes
- Invalid ARJ archive: too many extended headers
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3e1680583948c2c9.
Report an issue: GitHub.