can1357/oh-my-pi · error · ArchiveError
LZH member '${memberPath}' failed CRC-16 verification
Error message
LZH member '${memberPath}' failed CRC-16 verification What it means
Thrown by the LZH member extractor after decompression when the CRC-16 of the produced output does not match the CRC stored in the member's header. It means the archive bytes are corrupt, truncated, or the decompressor produced wrong output. The library verifies integrity before returning extracted data, so data is never silently wrong.
Source
Thrown at packages/utils/src/ar/lzh.ts:444
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;
}
function parseLzhHeader(bytes: Uint8Array, offset: number, options: FormatReadOptions): ParsedLzhHeader {
assertRange(bytes, offset, offset + 22, "header");View on GitHub (pinned to 9690622007)
Solutions
- Re-download or re-extract the archive from a trusted source and verify its checksum
- Repack the archive with a conforming LHA tool (e.g. lha) to regenerate a correct CRC
- Confirm the source file is not being read truncated (check file size and read stream completion)
- If you control the writer, ensure it computes the standard ARC CRC-16 over the raw member data
Example fix
// before: blindly reusing a partially downloaded archive
const bytes = await partialRead(url);
const archive = LzhReader.read(bytes);
// after: verify completeness first
const bytes = new Uint8Array(await Bun.file(path).arrayBuffer());
if (bytes.byteLength < expectedSize) throw new Error('incomplete archive');
const archive = LzhReader.read(bytes); Defensive patterns
Strategy: try-catch
Validate before calling
if (!(await Bun.file(path).exists())) throw new Error('archive missing'); Try / catch
try { extract(); } catch (err) { if (err instanceof ArchiveError) report(err.message); else throw err; } Prevention
- Always transfer archives with checksum verification
- Never resume-merge partial downloads of archives
When it happens
Trigger: Calling the LZH reader's member-extraction API on an archive whose compressed payload was corrupted in transit or on disk, or a member whose header CRC field does not match the actual data (hand-edited or badly written archives).
Common situations: Downloads that were truncated or corrupted, archives stored on failing media, archives created by non-conforming LZH writers that compute CRC differently, or byte-level tampering.
Related errors
- ARJ member '${memberPath}' has inconsistent stored size
- ARJ member '${memberPath}' failed CRC32 verification
- Invalid ${label} Huffman table: oversubscribed codes
- Invalid ${label} Huffman table: incomplete codes
- Invalid ${label} Huffman table: prefix collision
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/76e4d38966069070.
Report an issue: GitHub.