can1357/oh-my-pi · error · ArchiveError

Invalid LZH compression method '${method}'

Error message

Invalid LZH compression method '${method}'

What it means

Thrown when the 5-byte compression method string in an LZH header (bytes offset+2..offset+7, e.g. -lh5-) fails the LHA_METHOD_PATTERN validation. The bytes do not form a recognized LHA method signature, so the region is not a valid LZH member header.

Source

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

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

function parseLzhHeader(bytes: Uint8Array, offset: number, options: FormatReadOptions): ParsedLzhHeader {
	assertRange(bytes, offset, offset + 22, "header");
	const level = bytes[offset + 20]!;
	if (level > 2) throw new ArchiveError(`Unsupported LZH header level ${level}`);
	const method = String.fromCharCode(...bytes.subarray(offset + 2, offset + 7));
	if (!LHA_METHOD_PATTERN.test(method)) throw new ArchiveError(`Invalid LZH compression method '${method}'`);
	let packedSize = u32(bytes, offset + 7);
	let size = u32(bytes, offset + 11);
	let crc = 0;
	let legacyFilename: string | undefined;
	let mtimeMs: number | undefined;
	let osId = 0;
	let dataStart: number;
	const fields: LzhExtendedFields = {};

	if (level < 2) {
		const headerLength = bytes[offset]!;
		const minimum = level === 0 ? 22 : 25;
		if (headerLength < minimum) throw new ArchiveError(`Invalid LZH level-${level} header size`);
		const baseEnd = offset + headerLength + 2;
		assertRange(bytes, offset, baseEnd, "header");
		let sum = 0;
		for (let index = offset + 2; index < baseEnd; index++) sum = (sum + bytes[index]!) & 0xff;
		if (sum !== bytes[offset + 1]) throw new ArchiveError("Invalid LZH header checksum");

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the file is a genuine LHA archive (bytes 2-6 should look like -lhN- or -lzN-)
  2. Re-obtain the archive from a known-good source
  3. Check that you are not feeding a nested offset from a previous parse error

Example fix

// before: assuming .lzh extension means LZH
const archive = lzhRead(await Bun.file(name).arrayBuffer());
// after: sniff the method signature
const sig = String.fromCharCode(...new Uint8Array(buf, 2, 5));
if (!sig.startsWith('-') || !sig.endsWith('-')) throw new Error(`${name} is not LZH`);
const archive = lzhRead(buf);
Defensive patterns

Strategy: validation

Validate before calling

const sig = String.fromCharCode(...bytes.subarray(2, 7));
if (!/^-(lh|lz)[0-9a-z]-$/i.test(sig)) throw new Error('not LZH');

Try / catch

try { parse(); } catch (err) { if (err instanceof ArchiveError) reject(err.message); else throw err; }

Prevention

When it happens

Trigger: Parsing a file that is not LZH (wrong magic), an offset that has drifted due to earlier misparsing, or a corrupted header region.

Common situations: Opening a file with an .lzh extension that is actually another format, parsing concatenated archives where a member boundary was computed wrong, or bit rot in the header.

Related errors


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