can1357/oh-my-pi · error · ArchiveError

LZH member '${memberPath}' extracted to an unexpected size

Error message

LZH member '${memberPath}' extracted to an unexpected size

What it means

After decompression the reader verifies that the decoder produced exactly the declared uncompressed size. If a compression method's output length differs from the size in the header (or from the 0x42 64-bit-size override), the archive is internally inconsistent and the member is rejected before CRC verification.

Source

Thrown at packages/utils/src/ar/lzh.ts:442

			case "-lh5-":
				output = decompressLhStatic(packed, size, 1 << 13, 4, 14, "LZH -lh5-");
				break;
			case "-lh6-":
				output = decompressLhStatic(packed, size, 1 << 15, 5, 16, "LZH -lh6-");
				break;
			case "-lh7-":
				output = decompressLhStatic(packed, size, 1 << 16, 5, 17, "LZH -lh7-");
				break;
			case "-lzs-":
				output = decompressLzs(packed, size);
				break;
			case "-lh1-":
				throw new ArchiveError(`LZH member '${memberPath}' uses unsupported dynamic-Huffman method -lh1-`);
			default:
				throw new ArchiveError(`LZH member '${memberPath}' uses unsupported compression method ${this.#method}`);
		}
		if (output.byteLength !== size)
			throw new ArchiveError(`LZH member '${memberPath}' extracted to an unexpected size`);
		if (crc16Arc(output) !== this.#crc)
			throw new ArchiveError(`LZH member '${memberPath}' failed CRC-16 verification`);
		return output;
	}
}

interface ParsedLzhHeader {
	method: string;
	packedSize: number;
	size: number;
	dataStart: number;
	nextOffset: number;
	crc: number;
	path?: string;
	mtimeMs?: number;
	mode?: number;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-obtain the archive — a decompressed-size mismatch indicates data or header corruption
  2. Run the archive through an external extractor to identify the damaged member, then repack only the healthy members
  3. Compare the file against its original checksum to confirm transfer integrity and re-download if mismatched
  4. If you write LZH archives, ensure the size field equals the exact uncompressed byte count you feed the compressor

Example fix

null
Defensive patterns

Strategy: try-catch

Type guard

null

Try / catch

try {
	const data = await member.read();
} catch (err) {
	if (err instanceof ArchiveError && err.message.includes("extracted to an unexpected size")) {
		// decompressed output disagrees with header size — treat as corrupt member
	}
	throw err;
}

Prevention

When it happens

Trigger: Extracting an LZH member where the compressed stream decompresses to fewer or more bytes than the declared size — corrupt compressed data, wrong size fields (header or type-0x42 extended header), or a decoder/method mismatch from a corrupted method string.

Common situations: Bit-rotted or truncated compressed data; size fields edited by faulty tooling; archives that fail CRC anyway due to deeper corruption.

Related errors


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