can1357/oh-my-pi · error · ArchiveError
Invalid ARJ archive: no members
Error message
Invalid ARJ archive: no members
What it means
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.
Source
Thrown at packages/utils/src/ar/arj.ts:312
let mode: number | undefined;
if ((hostOs === 2 || hostOs === 8) && accessMode !== 0) {
mode = (isDirectory ? 0x4000 : 0x8000) | (accessMode & 0x0fff);
}
const rawMtime = u32(bytes, block.bodyStart + 8);
const mtimeMs =
hostOs === 2 || hostOs === 8 ? (rawMtime === 0 ? undefined : rawMtime * 1000) : dosTimeToMs(rawMtime);
entries.push({
path,
isDirectory,
size: isDirectory ? 0 : size,
mtimeMs,
mode,
storage: isDirectory
? undefined
: { type: "member", source: new ArjMemberSource(bytes, dataStart, packedSize, method, fileCrc) },
});
}
if (parsedCount === 0) throw new ArchiveError("Invalid ARJ archive: no members");
return entries;
};
View on GitHub (pinned to 9690622007)
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.
Example fix
// before
const entries = await readArj(bytes, options); // throws "no members"
// after
try {
const entries = await readArj(bytes, options);
} catch (e) {
if (e instanceof ArchiveError && e.message.includes("no members")) {
return []; // tolerate intentionally empty archives
}
throw e;
} Defensive patterns
Strategy: validation
Validate before calling
function assertArjHasMembers(bytes: Uint8Array): void {
// an ARJ with content is always larger than its main header + end-of-archive block
if (bytes.length < 64) throw new Error("File too small to be a populated ARJ archive");
} Try / catch
try {
entries = await readArj(source, options);
} catch (e) {
if (e instanceof ArchiveError && e.message === "Invalid ARJ archive: no members") {
logger.warn("ARJ contained zero members", { path });
return []; // treat as empty if your domain allows it
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Invalid ARJ local header
- Invalid ARJ archive: truncated ${what}
- Invalid ARJ ${field}: missing terminator
- ARJ member '${memberPath}' has inconsistent stored size
- ARJ member '${memberPath}' has invalid no-data method sizes
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/bafda823b389b228.
Report an issue: GitHub.