{"record":{"id":"bafda823b389b228","repo":"can1357/oh-my-pi","slug":"invalid-arj-archive-no-members","errorCode":null,"errorMessage":"Invalid ARJ archive: no members","messagePattern":"Invalid ARJ archive: no members","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/arj.ts","lineNumber":312,"sourceCode":"\t\tlet mode: number | undefined;\n\t\tif ((hostOs === 2 || hostOs === 8) && accessMode !== 0) {\n\t\t\tmode = (isDirectory ? 0x4000 : 0x8000) | (accessMode & 0x0fff);\n\t\t}\n\t\tconst rawMtime = u32(bytes, block.bodyStart + 8);\n\t\tconst mtimeMs =\n\t\t\thostOs === 2 || hostOs === 8 ? (rawMtime === 0 ? undefined : rawMtime * 1000) : dosTimeToMs(rawMtime);\n\t\tentries.push({\n\t\t\tpath,\n\t\t\tisDirectory,\n\t\t\tsize: isDirectory ? 0 : size,\n\t\t\tmtimeMs,\n\t\t\tmode,\n\t\t\tstorage: isDirectory\n\t\t\t\t? undefined\n\t\t\t\t: { type: \"member\", source: new ArjMemberSource(bytes, dataStart, packedSize, method, fileCrc) },\n\t\t});\n\t}\n\tif (parsedCount === 0) throw new ArchiveError(\"Invalid ARJ archive: no members\");\n\treturn entries;\n};\n","sourceCodeStart":294,"sourceCodeEnd":315,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/arj.ts#L294-L315","documentation":"After walking all ARJ blocks, if zero actual file members were indexed (only the main header and possibly an end-of-archive block were present), the reader considers the archive invalid. An ARJ that carries no member entries cannot yield a usable index, so it is rejected rather than returning an empty list.","triggerScenarios":"readArj completes its parse loop with parsedCount === 0 — the file had a plausible main header but no local file headers followed (e.g. an empty/truncated archive, a writer bug, or a non-archive file that passed the initial magic/header checks).","commonSituations":"Zero-byte-content archives produced by a misconfigured packaging job; archives truncated right after the main header; files corrupted or overwritten so only the header remains; fixtures built incorrectly in tests.","solutions":["Verify the archive with the original ARJ tool (`arj l archive.arj`) to confirm whether it truly contains files; re-create or re-download it if not.","Check the producer pipeline — an empty archive usually means the file list given to the packer was empty or all inputs failed.","Pre-check the file size/structure (expect more than just a ~30+ byte main header plus end block) before calling readArj and fail with your own clearer message.","If your code should tolerate empty archives, catch ArchiveError and treat it as an empty index after verifying the source is genuinely an ARJ."],"exampleFix":"// before\nconst entries = await readArj(bytes, options); // throws \"no members\"\n// after\ntry {\n  const entries = await readArj(bytes, options);\n} catch (e) {\n  if (e instanceof ArchiveError && e.message.includes(\"no members\")) {\n    return []; // tolerate intentionally empty archives\n  }\n  throw e;\n}","handlingStrategy":"validation","validationCode":"function assertArjHasMembers(bytes: Uint8Array): void {\n\t// an ARJ with content is always larger than its main header + end-of-archive block\n\tif (bytes.length < 64) throw new Error(\"File too small to be a populated ARJ archive\");\n}","typeGuard":null,"tryCatchPattern":"try {\n\tentries = await readArj(source, options);\n} catch (e) {\n\tif (e instanceof ArchiveError && e.message === \"Invalid ARJ archive: no members\") {\n\t\tlogger.warn(\"ARJ contained zero members\", { path });\n\t\treturn []; // treat as empty if your domain allows it\n\t}\n\tthrow e;\n}","preventionTips":["Verify packer jobs actually received input files before shipping the archive.","Spot-check archives with `arj l` after generation in CI.","Fail uploads smaller than a minimal valid populated ARJ at the boundary."],"tags":["archive","arj","empty-archive","validation"],"backgroundTag":"empty-archive-invalid","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}