can1357/oh-my-pi · error · ArchiveError
LZH member '${memberPath}' has inconsistent stored size
Error message
LZH member '${memberPath}' has inconsistent stored size What it means
For stored (uncompressed) methods -lh0- and -lz4-, the packed data length must exactly equal the declared uncompressed size, since there is no compression to transform it. A mismatch means the header sizes or the data extent are wrong, so the reader throws.
Source
Thrown at packages/utils/src/ar/lzh.ts:418
readonly #method: string;
readonly #crc: number;
constructor(archive: Uint8Array, start: number, packedSize: number, method: string, crc: number) {
this.#archive = archive;
this.#start = start;
this.#packedSize = packedSize;
this.#method = method;
this.#crc = crc;
}
async read(size: number, memberPath: string): Promise<Uint8Array> {
const packed = this.#archive.subarray(this.#start, this.#start + this.#packedSize);
let output: Uint8Array;
switch (this.#method) {
case "-lh0-":
case "-lz4-":
if (packed.byteLength !== size)
throw new ArchiveError(`LZH member '${memberPath}' has inconsistent stored size`);
output = packed.slice();
break;
case "-lh4-":
output = decompressLhStatic(packed, size, 1 << 12, 4, 13, "LZH -lh4-");
break;
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-":View on GitHub (pinned to 9690622007)
Solutions
- Re-obtain the archive; for stored members the sizes must match and a mismatch proves corruption
- Check whether the file was truncated (compare to expected size/checksum) and re-download
- Repack the archive with a standard tool (7-Zip, lha) to regenerate consistent headers
- If you write LZH archives, set packedSize === size for -lh0-/-lz4- members
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
// For stored members, packed size must equal declared size
function storedSizeConsistent(packedSize: number, size: number, method: string): boolean {
return !(method === "-lh0-" || method === "-lz4-") || packedSize === size;
} Type guard
function isStoredMethod(method: string): method is "-lh0-" | "-lz4-" {
return method === "-lh0-" || method === "-lz4-";
} Try / catch
try {
const data = await member.read();
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("inconsistent stored size")) {
// header/data corruption — re-download or repack
}
throw err;
} Prevention
- Compare archive file size to the sum of member sizes when generating archives
- Re-verify downloads against source checksums
- Never hand-patch LZH size fields; repack instead
When it happens
Trigger: Calling member read/extract on an LZH entry whose method is -lh0- or -lz4- but whose stored packedSize differs from the declared uncompressed size — typically after header corruption, a bad 0x42 64-bit-size override, or truncation of the archive buffer.
Common situations: Corrupted or truncated stored archives; archives where extended headers misreport sizes; self-written LZH tooling that writes inconsistent size fields.
Related errors
- LZH member '${memberPath}' extracted to an unexpected size
- ARJ member '${memberPath}' extracted to an unexpected size
- 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/d1c10d7878c293a8.
Report an issue: GitHub.