can1357/oh-my-pi · error · ArchiveError
Invalid ZIP archive: malformed LZMA properties for '${member
Error message
Invalid ZIP archive: malformed LZMA properties for '${memberPath}' What it means
A ZIP member compressed with method 14 (LZMA) must begin with a 4-byte LZMA SDK header whose bytes 2 and 3 are the properties size marker 0x05 0x00, followed by 5 bytes of LZMA properties and the LZMA stream. This member's compressed data is shorter than 9 bytes or lacks the 0x05 0x00 marker, so it is not a valid LZMA-in-ZIP payload.
Source
Thrown at packages/utils/src/ar/zip.ts:345
}
async function decodeMember(
compressed: Uint8Array,
method: number,
size: number,
memberPath: string,
): Promise<Uint8Array> {
try {
switch (method) {
case 0:
return compressed;
case 8:
return zlib.inflateRawSync(compressed, { maxOutputLength: Math.max(size, 1) });
case 12:
return await bzip2Decompress(compressed, size);
case 14: {
if (compressed.byteLength < 9 || compressed[2] !== 5 || compressed[3] !== 0) {
throw new ArchiveError(`Invalid ZIP archive: malformed LZMA properties for '${memberPath}'`);
}
return await lzmaDecompress(compressed.subarray(4, 9), compressed.subarray(9), size);
}
case 20:
case 93:
return await zstdDecompress(compressed, size);
case 95:
return await xzDecompress(compressed, size);
default:
throw new ArchiveError(`Unsupported ZIP compression method ${method} for '${memberPath}'`);
}
} catch (error) {
throw archiveError(error, `Failed to decompress ZIP member '${memberPath}'`);
}
}
class ZipMemberSource implements MemberSource {
readonly #source: ByteSource;View on GitHub (pinned to 9690622007)
Solutions
- Verify the archive with unzip -t / 7z t and re-obtain if corrupt.
- Repack the archive with 7-Zip (7z a -tzip -m0=lzma) so the header/properties bytes are written correctly.
- If you write LZMA entries yourself, prepend the 4-byte header (version 2 bytes, then 0x05 0x00) plus the 5-byte LZMA properties block before the stream, matching the ZIP APPNOTE method-14 layout.
Example fix
// before: raw LZMA stream stored directly in the entry // after // payload = concat(Uint8Array([0x02,0x00,0x05,0x00]), lzmaProperties5Bytes, lzmaStream);
Defensive patterns
Strategy: try-catch
Validate before calling
const res = await $`unzip -lv archive.zip`.quiet().nothrow();
if (res.exitCode === 0 && (await res.text()).includes("LZMA")) {
// method 14 present: ensure archive came from a conformant writer (e.g. 7-Zip)
} Try / catch
try {
await archive.readMember(path);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("malformed LZMA properties")) {
// repack with 7z: 7z x corrupted.zip -o tmp && 7z a -tzip -m0=lzma fixed.zip tmp/*
} else throw err;
} Prevention
- Only create LZMA ZIP entries with 7-Zip or another APPNOTE-conformant tool.
- Verify integrity (unzip -t) before ingesting LZMA archives.
- Avoid hand-rolled LZMA-in-ZIP writers.
When it happens
Trigger: Reading a ZIP entry whose compression method is 14 whose stored data is truncated (fewer than 9 bytes) or whose bytes at offsets 2-3 are not 0x05,0x00 — i.e. not produced by a conformant LZMA ZIP writer.
Common situations: Corrupted or truncated downloads of LZMA-compressed archives, hand-rolled writers that store raw LZMA without the 5-byte ZIP LZMA properties header, malicious/fuzzed archives.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid ZIP archive: extended timestamp extra field is too s
- Invalid ZIP archive: missing ZIP64 extra field
- Invalid ZIP archive: malformed ZIP64 extra field
- Invalid ZIP archive: size mismatch for '${memberPath}' (expe
- Invalid EPUB: missing content.opf
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ec0aaae6c9149c1d.
Report an issue: GitHub.