can1357/oh-my-pi · error · ArchiveError

Invalid CAB archive: LZX block produced the wrong byte count

Error message

Invalid CAB archive: LZX block produced the wrong byte count

What it means

#decodeRun must produce exactly the requested number of bytes (run); producing fewer means the LZX block ended early or its symbols decoded inconsistently with the declared block length. The decoder aborts rather than return a short, silently-corrupt buffer.

Source

Thrown at packages/utils/src/ar/codecs/lzx.ts:211

		}
		if (outputSize === 0) return new Uint8Array(0);
		const reader = new LzxBitReader(bytes);
		if (!this.#headerRead) {
			if (reader.readBits(1) !== 0) {
				const high = reader.readBits(16);
				const low = reader.readBits(16);
				this.#intelFileSize = signedUInt32((high * 0x10000 + low) >>> 0);
			}
			this.#headerRead = true;
		}

		const raw = new Uint8Array(outputSize);
		let outputPosition = 0;
		while (outputPosition < outputSize) {
			if (this.#blockRemaining === 0) this.#readBlockHeader(reader);
			const run = Math.min(this.#blockRemaining, outputSize - outputPosition);
			const produced = this.#decodeRun(reader, raw, outputPosition, run);
			if (produced !== run) throw new ArchiveError("Invalid CAB archive: LZX block produced the wrong byte count");
			outputPosition += produced;
			this.#blockRemaining -= produced;
		}
		if (this.#blockRemaining === 0 && this.#blockType === 3 && this.#uncompressedPadding) {
			reader.readByte();
			this.#uncompressedPadding = false;
		}
		reader.alignWord();

		const translated = this.#translateE8(raw);
		this.#frame++;
		return translated;
	}

	#readBlockHeader(reader: LzxBitReader): void {
		if (this.#blockType === 3 && this.#uncompressedPadding) reader.readByte();
		this.#uncompressedPadding = false;
		this.#blockType = reader.readBits(3);

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify CAB integrity and re-obtain the archive.
  2. Ensure each decompressFrame call gets exactly one CFDATA block's compressed bytes in order.
  3. Recompress with a standard CAB tool.
  4. Create a fresh LzxDecoder per folder and never reuse one across folders or after a thrown error.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const out = decoder.decompressFrame(blockData, blockOutSize)
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes('wrong byte count')) {
    throw new Error('CAB archive corrupt: block decoded to fewer bytes than declared')
  }
  throw err
}

Prevention

When it happens

Trigger: A corrupt bitstream where a match/length sequence terminates before filling the requested run, or trees/offsets that cause the decode loop to end prematurely (e.g. after the 'match crosses boundary' guard would have fired in an inconsistent state).

Common situations: Corrupted CAB data, wrong block bytes passed to decompressFrame, streams from non-conforming encoders whose block length header disagrees with the encoded symbols.

Related errors


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