{"record":{"id":"ad81e46aedd56c91","repo":"can1357/oh-my-pi","slug":"invalid-lzh-archive-no-members","errorCode":null,"errorMessage":"Invalid LZH archive: no members","messagePattern":"Invalid LZH archive: no members","errorType":"validation","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/lzh.ts","lineNumber":657,"sourceCode":"\t\t\t\tstorage: { type: \"link\", targetPath, resolveTarget: false },\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tentries.push({\n\t\t\tpath: header.path,\n\t\t\tisDirectory,\n\t\t\tsize: isDirectory ? 0 : header.size,\n\t\t\tmtimeMs: header.mtimeMs,\n\t\t\tmode: header.mode,\n\t\t\tstorage: isDirectory\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\ttype: \"member\",\n\t\t\t\t\t\tsource: new LzhMemberSource(bytes, header.dataStart, header.packedSize, header.method, header.crc),\n\t\t\t\t\t},\n\t\t});\n\t}\n\tif (entries.length === 0 && parsedCount === 0) throw new ArchiveError(\"Invalid LZH archive: no members\");\n\treturn entries;\n};\n","sourceCodeStart":639,"sourceCodeEnd":660,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/lzh.ts#L639-L660","documentation":"readLzh parsed the byte buffer but found no member headers at all: the loop over header offsets never executed (first byte was 0 or the buffer ended immediately) after the initial LZH header sniff passed. The library throws because an LZH archive with zero members is not a usable container. This indicates the input is not really an LZH archive or is a degenerate/empty file that merely sniffs as LZH.","triggerScenarios":"Calling the archive open/browse API on a path or bytes whose format was detected as LZH (readLzh via the format registry) but whose content begins with a 0x00 byte or has no parseable member headers, so entries.length === 0 && parsedCount === 0 at lzh.ts:657.","commonSituations":"Renamed or truncated downloads (a corrupt/empty file with an .lzh extension), placeholder files created by failed transfers, or misrouted format detection that sniffed a wrong-format blob as LZH.","solutions":["Verify the file is a genuine LZH archive (magic/method bytes like '-lh0-') with an external tool or hex inspection; re-download or re-export it if not.","Check the caller supplied the intended path/bytes, not an empty or partially-written file.","Confirm the file size is non-trivial; a 0/1-byte file cannot contain members.","Catch ArchiveError and surface a clear 'not a valid archive' message to the user instead of retrying."],"exampleFix":"// before\nconst entries = await openArchive(inputPath);\n// after\nif ((await Bun.file(inputPath).size) < 32) throw new Error(`${inputPath} is not a valid LZH archive (too small)`);\nconst entries = await openArchive(inputPath);","handlingStrategy":"try-catch","validationCode":"import { sniffLzh } from \"@oh-my-pi/pi-utils/ar/lzh\"; // or check first bytes manually\nconst bytes = new Uint8Array(await Bun.file(p).arrayBuffer());\nif (bytes.length < 32 || !sniffLzh(bytes)) throw new Error(`${p} is not a valid LZH archive`);","typeGuard":null,"tryCatchPattern":"try {\n  const reader = await openArchive(p);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"no members\")) {\n    throw new Error(`${p} is empty or not a real LZH archive`);\n  }\n  throw err;\n}","preventionTips":["Verify file size (>header+member minimum) before opening.","Pre-check the archive with a sniff/inspect call before extraction.","Treat zero-member archives from downloads as transfer failures and re-fetch.","Log the input path and size when surfacing ArchiveError to users."],"tags":["archive","lzh","invalid-archive","corrupt-input"],"backgroundTag":"invalid-archive-format","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}