can1357/oh-my-pi · error · ArchiveError

Invalid LZH archive: no members

Error message

Invalid LZH archive: no members

What it means

readLzh parsed the byte buffer but found no member headers at all: the loop over header offsets never executed (first byte was 0 or the buffer ended immediately) after the initial LZH header sniff passed. The library throws because an LZH archive with zero members is not a usable container. This indicates the input is not really an LZH archive or is a degenerate/empty file that merely sniffs as LZH.

Source

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

				storage: { type: "link", targetPath, resolveTarget: false },
			});
			continue;
		}
		entries.push({
			path: header.path,
			isDirectory,
			size: isDirectory ? 0 : header.size,
			mtimeMs: header.mtimeMs,
			mode: header.mode,
			storage: isDirectory
				? undefined
				: {
						type: "member",
						source: new LzhMemberSource(bytes, header.dataStart, header.packedSize, header.method, header.crc),
					},
		});
	}
	if (entries.length === 0 && parsedCount === 0) throw new ArchiveError("Invalid LZH archive: no members");
	return entries;
};

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the file is a genuine LZH archive (magic/method bytes like '-lh0-') with an external tool or hex inspection; re-download or re-export it if not.
  2. Check the caller supplied the intended path/bytes, not an empty or partially-written file.
  3. Confirm the file size is non-trivial; a 0/1-byte file cannot contain members.
  4. Catch ArchiveError and surface a clear 'not a valid archive' message to the user instead of retrying.

Example fix

// before
const entries = await openArchive(inputPath);
// after
if ((await Bun.file(inputPath).size) < 32) throw new Error(`${inputPath} is not a valid LZH archive (too small)`);
const entries = await openArchive(inputPath);
Defensive patterns

Strategy: try-catch

Validate before calling

import { sniffLzh } from "@oh-my-pi/pi-utils/ar/lzh"; // or check first bytes manually
const bytes = new Uint8Array(await Bun.file(p).arrayBuffer());
if (bytes.length < 32 || !sniffLzh(bytes)) throw new Error(`${p} is not a valid LZH archive`);

Try / catch

try {
  const reader = await openArchive(p);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes("no members")) {
    throw new Error(`${p} is empty or not a real LZH archive`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling the archive open/browse API on a path or bytes whose format was detected as LZH (readLzh via the format registry) but whose content begins with a 0x00 byte or has no parseable member headers, so entries.length === 0 && parsedCount === 0 at lzh.ts:657.

Common situations: Renamed or truncated downloads (a corrupt/empty file with an .lzh extension), placeholder files created by failed transfers, or misrouted format detection that sniffed a wrong-format blob as LZH.

Related errors


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