{"record":{"id":"67409614ac32ddcf","repo":"can1357/oh-my-pi","slug":"multi-volume-lzh-archives-are-unsupported","errorCode":null,"errorMessage":"Multi-volume LZH archives are unsupported","messagePattern":"Multi-volume LZH archives are unsupported","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/lzh.ts","lineNumber":365,"sourceCode":"\ttype: number,\n\tdata: Uint8Array,\n\tabsoluteDataOffset: number,\n\tfields: LzhExtendedFields,\n): void {\n\tswitch (type) {\n\t\tcase 0x00:\n\t\t\tif (data.byteLength < 2) throw new ArchiveError(\"Invalid LZH common extended header\");\n\t\t\tfields.commonCrc = u16(data, 0);\n\t\t\tfields.commonCrcOffset = absoluteDataOffset;\n\t\t\tbreak;\n\t\tcase 0x01:\n\t\t\tfields.filename = decodeLegacy(data);\n\t\t\tbreak;\n\t\tcase 0x02:\n\t\t\tfields.directory = decodeLegacy(data).replaceAll(\"ÿ\", \"/\");\n\t\t\tbreak;\n\t\tcase 0x39:\n\t\t\tthrow new ArchiveError(\"Multi-volume LZH archives are unsupported\");\n\t\tcase 0x41:\n\t\t\tif (data.byteLength >= 16) {\n\t\t\t\tconst low = u32(data, 8);\n\t\t\t\tconst high = u32(data, 12);\n\t\t\t\tconst filetime = low + high * 0x100000000;\n\t\t\t\tif (Number.isSafeInteger(filetime)) fields.mtimeMs = filetime / 10_000 - 11_644_473_600_000;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 0x42:\n\t\t\tif (data.byteLength < 16) throw new ArchiveError(\"Invalid LZH 64-bit size extended header\");\n\t\t\tfields.packedSize = u64(data, 0);\n\t\t\tfields.size = u64(data, 8);\n\t\t\tbreak;\n\t\tcase 0x44:\n\t\t\tfields.unicodeFilename = decodeUtf16(data);\n\t\t\tbreak;\n\t\tcase 0x45:\n\t\t\tfields.unicodeDirectory = decodeUtf16(data).replaceAll(\"ÿ\", \"/\");","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/lzh.ts#L347-L383","documentation":"Extended header type 0x39 marks a multi-volume (split/disk-spanning) LZH archive. This library reads single in-memory archives only and cannot resolve members continued across volumes, so it refuses the archive up front.","triggerScenarios":"Reading a .lzh file that is one part of a multi-disk/multi-volume set created with disk spanning (e.g. old backup sets spanning floppies or numbered .lzh/.l00/.l01 files).","commonSituations":"Recovering legacy backup archives split across disks; users supplying only the first volume of a set; archival migration of multi-part LHA files.","solutions":["Supply all volumes of the set and rejoin/split-merge them into a single archive using a tool that supports multi-volume LHA (e.g. LHA/UNLHA32 on the original media) before loading","Re-create the archive as a single-volume .lzh (or a different format like zip) with all members included","If you only need specific members, extract them with an external multi-volume-aware tool first, then repack individually","Detect volume numbering in your app (e.g. .lzh/.l00/.l01 suffixes) and prompt the user to merge before calling the reader"],"exampleFix":"null","handlingStrategy":"validation","validationCode":"// Detect likely multi-volume LHA sets before calling the reader\nimport * as fs from \"node:fs\";\nfunction looksLikeMultiVolumeSet(basePath: string): boolean {\n\treturn /\\.l(?:zh|ha|[0-9]{2})$/i.test(basePath) &&\n\t\tfs.existsSync(basePath.replace(/\\.l(?:zh|ha)$/i, \".l00\"));\n}","typeGuard":"null","tryCatchPattern":"try {\n\tconst entries = await readArchive(lzhBytes);\n} catch (err) {\n\tif (err instanceof ArchiveError && err.message.includes(\"Multi-volume\")) {\n\t\t// prompt user to merge volumes with a multi-volume-aware tool first\n\t}\n\tthrow err;\n}","preventionTips":["Keep multi-volume sets together and merge them before ingesting","Convert legacy split archives to single-volume zip/lzh during archival migration","Detect numbered volume suffixes (.l00, .l01) in file intake logic"],"tags":["archive","lzh","multi-volume","unsupported-feature"],"backgroundTag":"unsupported-archive-feature","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}