can1357/oh-my-pi · error · ArchiveError

Archive is too large to read in memory

Error message

Archive is too large to read in memory (${formatBytes(size)} > ${formatBytes(limits.maxInMemorySize)} limit)

What it means

assertInMemorySize rejects archives that would be fully loaded into memory beyond the configured limit (default maxInMemorySize is 256 MiB in DEFAULT_ARCHIVE_LIMITS). The message reports both the measured size and the limit via formatBytes so you can see by how much the archive overshoots.

Solutions

  1. Pass custom limits raising maxInMemorySize for this call: { limits: { ...DEFAULT_ARCHIVE_LIMITS, maxInMemorySize: 2 * 1024 * 1024 * 1024 } } (mind actual available RAM)
  2. Stream/extract the archive with a native tool (cpio, cabextract, dpkg-deb) instead of materializing it in JS
  3. Split the archive or read only needed members via targeted tooling
  4. Check for decompression bombs if the size seemed unexpectedly large; reject untrusted inputs

Example fix

// before
const entries = await readCpio(bigBuffer); // >256MiB -> ArchiveError
// after
import { DEFAULT_ARCHIVE_LIMITS } from '.../ar/limits';
const entries = await readCpio(bigBuffer, {
  limits: { ...DEFAULT_ARCHIVE_LIMITS, maxInMemorySize: 1024 * 1024 * 1024 },
});
Defensive patterns

Strategy: try-catch

Validate before calling

import { stat } from 'node:fs/promises';
import { DEFAULT_ARCHIVE_LIMITS } from '.../ar/limits';
const { size } = await stat(path);
if (size > DEFAULT_ARCHIVE_LIMITS.maxInMemorySize) {
  throw new Error(`archive ${size} bytes exceeds in-memory limit; stream instead`);
}

Type guard

null

Try / catch

try {
  entries = await readCpio(source);
} catch (err) {
  if (err instanceof ArchiveError && err.message.startsWith('Archive is too large to read in memory')) {
    const m = err.message.match(/\((.*?) > (.*?) limit\)/); // parse size vs limit
    // raise limits explicitly or switch to native streaming tools
  } else throw err;
}

Prevention

When it happens

Trigger: Calling a materializing reader (readArj, readCabArchive, readCpio, readDeb -> decompressDebTar, etc.) with default limits on an archive (or a decompressed deb control/data tar member) larger than limits.maxInMemorySize — e.g. a 500 MiB cpio or a deb whose data.tar decompresses past 256 MiB.

Common situations: Reading large system images/backup archives (big cpio/cab), .deb packages with huge data payloads, CI machines where callers assumed smaller artifacts, or decompression bombs whose inflated size crosses the limit.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/b632aa18e91f4ce5. Report an issue: GitHub.

Appendix: source

Thrown at packages/utils/src/ar/limits.ts:41

	maxLinkDepth: number;
}

export const DEFAULT_ARCHIVE_LIMITS: ArchiveLimits = {
	maxEntries: 1_000_000,
	maxInMemorySize: 256 * 1024 * 1024,
	maxIndexSize: 64 * 1024 * 1024,
	maxMemberSize: 64 * 1024 * 1024,
	maxPathBytes: 4096,
	maxLinkDepth: 40,
};

/** Reject an archive that would be fully materialized beyond `maxInMemorySize`. */
export function assertInMemorySize(size: number, limits: ArchiveLimits): void {
	if (!Number.isSafeInteger(size) || size < 0) {
		throw new ArchiveError("Archive is too large to read safely");
	}
	if (size > limits.maxInMemorySize) {
		throw new ArchiveError(
			`Archive is too large to read in memory (${formatBytes(size)} > ${formatBytes(limits.maxInMemorySize)} limit)`,
		);
	}
}

/** Reject archive metadata (index/header) beyond `maxIndexSize`. */
export function assertIndexSize(size: number, limits: ArchiveLimits, what: string): void {
	if (!Number.isSafeInteger(size) || size < 0) {
		throw new ArchiveError(`Invalid archive: ${what} has an invalid size`);
	}
	if (size > limits.maxIndexSize) {
		throw new ArchiveError(
			`Archive ${what} is too large (${formatBytes(size)} > ${formatBytes(limits.maxIndexSize)} limit)`,
		);
	}
}

/**

View on GitHub (pinned to 9690622007)