{"record":{"id":"11817d1cf46ae51a","repo":"can1357/oh-my-pi","slug":"lzh-uses-the-incompatible-lhark-lh7-variant","errorCode":null,"errorMessage":"LZH uses the incompatible LHARK -lh7- variant","messagePattern":"LZH uses the incompatible LHARK -lh7- variant","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/lzh.ts","lineNumber":561,"sourceCode":"\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (extensionSize < 3 || cursor + extensionSize > headerEnd)\n\t\t\t\tthrow new ArchiveError(\"Invalid LZH extended header size\");\n\t\t\tif (++extensionCount > 65_535) throw new ArchiveError(\"Invalid LZH archive: too many extended headers\");\n\t\t\tconst type = bytes[cursor + 2]!;\n\t\t\tconst data = bytes.subarray(cursor + 3, cursor + extensionSize);\n\t\t\tif (type === 0x01 || type === 0x02 || type === 0x44 || type === 0x45) {\n\t\t\t\tassertArchivePathBytes(data.byteLength, \"member path\", options.limits.maxPathBytes);\n\t\t\t}\n\t\t\tprocessExtendedHeader(type, data, cursor + 3, fields);\n\t\t\tcursor += extensionSize;\n\t\t}\n\t\tif (cursor !== headerEnd) throw new ArchiveError(\"Invalid LZH level-2 extended header chain\");\n\t\tdataStart = headerEnd;\n\t\tpackedSize = fields.packedSize ?? packedSize;\n\t}\n\tif (level === 1 && osId === 0x20 && method === \"-lh7-\") {\n\t\tthrow new ArchiveError(\"LZH uses the incompatible LHARK -lh7- variant\");\n\t}\n\n\tsize = fields.size ?? size;\n\tmtimeMs = fields.mtimeMs ?? mtimeMs;\n\tconst mode = fields.mode;\n\tif (fields.commonCrc !== undefined) {\n\t\tconst relative = fields.commonCrcOffset! - offset;\n\t\tif (crc16WithZeroRange(bytes.subarray(offset, dataStart), relative, relative + 2) !== fields.commonCrc) {\n\t\t\tthrow new ArchiveError(\"Invalid LZH common header CRC-16\");\n\t\t}\n\t}\n\tconst filename = fields.unicodeFilename ?? fields.filename ?? legacyFilename ?? \"\";\n\tconst directory = fields.unicodeDirectory ?? fields.directory ?? \"\";\n\tconst rawPath = `${directory}${directory && !/[\\\\/]$/.test(directory) ? \"/\" : \"\"}${filename}`;\n\tassertArchivePathString(rawPath, \"member path\", options.limits.maxPathBytes);\n\tassertArchiveMemberSize(size, rawPath || \"<unnamed>\", options.limits);\n\tassertRange(bytes, dataStart, dataStart + packedSize, \"member data\");\n\treturn {","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/lzh.ts#L543-L579","documentation":"LHARK is an unofficial LZH variant that reuses the -lh7- method with level-1 headers and OS id 0x20 (MS-DOS) but changes the compression algorithm's tables. It is not decodable by this library, so it is detected and rejected up front instead of producing garbage output.","triggerScenarios":"readLzh() on a level-1 header with osId 0x20 and compression method -lh7-.","commonSituations":"Archives created by the LHARK archiver (rare, mostly from Japanese/DOS-era sources) mislabeled as standard LHA; users confusing LHARK files with regular .lzh files.","solutions":["Identify the file as LHARK-created; use a tool that supports LHARK (e.g. the original LHARK under DOS emulation) to extract it.","Re-compress the contents with a standard LHA tool (-lh5-/-lh6-/-lh7- from LHA/lhasa) and use the new archive.","If you only need the contents, extract externally and feed individual files to your pipeline instead.","Catch ArchiveError with this message and surface a clear 'LHARK variant unsupported' notice to end users."],"exampleFix":"// before\nconst entries = await readLzh(source, options);\n// after\ntry {\n  const entries = await readLzh(source, options);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"LHARK\")) {\n    throw new Error(\"This is a LHARK archive; convert it with a standard LHA tool first\");\n  }\n  throw err;\n}","handlingStrategy":"fallback","validationCode":"// detect the LHARK signature before reading\nconst bytes = await readAllBytes(source);\nconst method = String.fromCharCode(bytes[2], bytes[3], bytes[4], bytes[5], bytes[6]);\nif (method === \"-lh7-\" && bytes[20] === 1) {\n  throw new Error(\"LHARK variant detected — convert with an LHARK-aware tool first\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  const entries = await readLzh(source, options);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"LHARK\")) {\n    return extractLharkExternally(path); // fallback path\n  }\n  throw err;\n}","preventionTips":["Screen archives for the LHARK signature (-lh7- level-1) in ingest pipelines","Convert LHARK archives to standard LHA during ingestion","Document that only standard LZH levels 0-2 methods are supported"],"tags":["archive","lzh","unsupported-format","compatibility"],"backgroundTag":"unsupported-archive-variant","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}