can1357/oh-my-pi · error · ArchiveError

Unsupported CAB compression method: Quantum (level ${descrip

Error message

Unsupported CAB compression method: Quantum (level ${description.parameter})

What it means

The reader supports CAB compression methods None(0), Deflate(1), and LZX(3), but Quantum (method 2) has no decoder and is rejected explicitly, including its window parameter. Quantum is an obsolete IBM/MS compression scheme rarely needed today. This throws before any data is read, as soon as #decode inspects the folder description.

Source

Thrown at packages/utils/src/ar/cab.ts:130

	readonly #limits: ArchiveLimits;
	#decoded?: Promise<Uint8Array>;

	constructor(source: ByteSource, description: CabFolderDescription, dataReserveSize: number, limits: ArchiveLimits) {
		this.#source = source;
		this.#description = description;
		this.#dataReserveSize = dataReserveSize;
		this.#limits = limits;
	}

	readAll(): Promise<Uint8Array> {
		this.#decoded ??= this.#decode();
		return this.#decoded;
	}

	async #decode(): Promise<Uint8Array> {
		const description = this.#description;
		if (description.method === 2) {
			throw new ArchiveError(`Unsupported CAB compression method: Quantum (level ${description.parameter})`);
		}
		if (description.method > 3) {
			throw new ArchiveError(`Unsupported CAB compression method: ${description.method}`);
		}
		if (description.method === 3 && (description.parameter < 15 || description.parameter > 21)) {
			throw new ArchiveError(`Unsupported CAB LZX window size: ${description.parameter} bits (expected 15-21)`);
		}

		const compressedSize = description.dataEnd - description.dataStart;
		assertInMemorySize(compressedSize, this.#limits);
		const bytes = await readExact(this.#source, description.dataStart, description.dataEnd);
		let position = 0;
		let outputSize = 0;
		for (let block = 0; block < description.blockCount; block++) {
			if (position + DATA_BLOCK_SIZE + this.#dataReserveSize > bytes.byteLength) {
				throw new ArchiveError("Invalid CAB archive: truncated CFDATA header");
			}
			const compressed = readUInt16LE(bytes, position + 4);

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-compress the archive with a supported method: unpack with cabextract (it supports Quantum via libmspack) and repack with Deflate or LZX, e.g. `lcab -m deflate` or plain `lcab` (store).
  2. Extract contents with `cabextract file.cab` outside this library and consume the extracted files instead.
  3. If the archive is from an installer, use a dedicated installer-extraction tool (innoextract, 7z) to obtain the payload.
  4. Check whether the CAB-creating tool has an option to use MSZIP/Deflate instead of Quantum and re-export.
  5. If you must read Quantum in-process, add/enable a Quantum decoder or find a JS Quantum implementation and contribute it as method 2 support.

Example fix

// before: Quantum CAB throws in readAll
await openCab('legacy.cab').then(r => r.readAll()); // Unsupported ... Quantum (level 2)
// after: convert with cabextract + lcab
cabextract legacy.cab -d out/
lcab out/ converted.cab
await openCab('converted.cab').then(r => r.readAll());
Defensive patterns

Strategy: validation

Validate before calling

// Peek the folder compression method (typeCompress low bits) before full read
const method = readFolderCompressionMethod(cabBytes); // your own header peek
if (method === 2) throw new Error('CAB uses unsupported Quantum compression — convert with cabextract/lcab first');

Type guard

function isSupportedCabMethod(m: number): boolean {
  return m === 0 || m === 1 || m === 3;
}

Try / catch

try {
  return await readCabArchive(bytes);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes('Quantum')) {
    throw new Error('Convert this legacy Quantum CAB to MSZIP/LZX before in-process reading');
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling readAll() (directly or via the public extract/read APIs) on a CAB whose CFFOLDER typeCompress field indicates method 2 (Quantum), regardless of the quantum level in the parameter field.

Common situations: Old CABs produced by MS-DOS-era tools (Diamond 1.x era, early InstallShield packages) that defaulted to Quantum; legacy software distribution archives from the 1990s; archives re-compressed with Quantum to shrink floppy-sized media.

Related errors


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