can1357/oh-my-pi · error · ArchiveError
Invalid LZH Unix permissions extended header
Error message
Invalid LZH Unix permissions extended header
What it means
Extended header type 0x50 stores Unix permission bits as a u16 and must be at least 2 bytes long. A shorter payload means the header chain is malformed, so the reader throws rather than guessing a mode.
Source
Thrown at packages/utils/src/ar/lzh.ts:386
const low = u32(data, 8);
const high = u32(data, 12);
const filetime = low + high * 0x100000000;
if (Number.isSafeInteger(filetime)) fields.mtimeMs = filetime / 10_000 - 11_644_473_600_000;
}
break;
case 0x42:
if (data.byteLength < 16) throw new ArchiveError("Invalid LZH 64-bit size extended header");
fields.packedSize = u64(data, 0);
fields.size = u64(data, 8);
break;
case 0x44:
fields.unicodeFilename = decodeUtf16(data);
break;
case 0x45:
fields.unicodeDirectory = decodeUtf16(data).replaceAll("ÿ", "/");
break;
case 0x50:
if (data.byteLength < 2) throw new ArchiveError("Invalid LZH Unix permissions extended header");
fields.mode = u16(data, 0);
break;
case 0x54:
if (data.byteLength < 4) throw new ArchiveError("Invalid LZH Unix timestamp extended header");
fields.mtimeMs = u32(data, 0) * 1000;
break;
}
}
class LzhMemberSource implements MemberSource {
readonly #archive: Uint8Array;
readonly #start: number;
readonly #packedSize: number;
readonly #method: string;
readonly #crc: number;
constructor(archive: Uint8Array, start: number, packedSize: number, method: string, crc: number) {
this.#archive = archive;View on GitHub (pinned to 9690622007)
Solutions
- Re-obtain the archive — the header size chain is corrupt
- Verify with an external tool (7-Zip, lha) which member's headers are damaged and repair/skip it
- If you write LZH archives, ensure type 0x50 headers carry exactly 2 bytes (u16 LE mode) plus the size trailer
- Treat missing permission info gracefully in your app by catching ArchiveError and defaulting modes
Example fix
null
Defensive patterns
Strategy: try-catch
Type guard
null
Try / catch
try {
const entries = await readArchive(lzhBytes);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("Unix permissions extended header")) {
// fall back to default modes or re-acquire the archive
}
throw err;
} Prevention
- Validate Unix-created .lzh files with lhasa/7-Zip before automated ingestion
- Do not rewrite extended headers with ad-hoc scripts
- Store and check transfer checksums
When it happens
Trigger: Reading an LZH level-1/2 member whose extended-header chain contains a type 0x50 entry with fewer than 2 data bytes — corrupt size field, truncation, or a buggy writer.
Common situations: Unix-created .lzh archives (LHA for Linux, lhasa) with damaged headers; archives whose extended headers were rewritten by scripts; partially recovered files.
Related errors
- Invalid LZH Unicode path header: odd UTF-16 length
- Invalid LZH common extended header
- Invalid LZH Unix timestamp extended header
- Unable to read LZH archive: ${error instanceof Error ? error
- Invalid CAB archive: reserved CFHEADER fields must be zero
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6572b0ad5a79f0b0.
Report an issue: GitHub.