can1357/oh-my-pi · error · ArchiveError
Multi-volume ARJ members are unsupported
Error message
Multi-volume ARJ members are unsupported
What it means
Bits 2-3 (0x0c) of an ARJ local file header's flags byte mark the member as part of a multi-volume sequence (continued on another volume, in various directions). The single-buffer reader cannot assemble members spanning volumes, so it rejects archives containing such members.
Source
Thrown at packages/utils/src/ar/arj.ts:268
const entries: ArchiveIndexEntry[] = [];
let offset = main.nextOffset;
let metadataSize = main.metadataSize;
let parsedCount = 0;
for (;;) {
const block = parseArjBlock(bytes, offset, options);
metadataSize += block.metadataSize;
assertIndexSize(metadataSize, options.limits, "index");
if (block.isEnd) break;
assertEntryCount(++parsedCount, options.limits);
const firstHeaderSize = bytes[block.bodyStart]!;
if (firstHeaderSize < 30 || firstHeaderSize > block.bodySize) throw new ArchiveError("Invalid ARJ local header");
const hostOs = bytes[block.bodyStart + 3]!;
const flags = bytes[block.bodyStart + 4]!;
const method = bytes[block.bodyStart + 5]!;
const fileType = bytes[block.bodyStart + 6]!;
if ((flags & 0x01) !== 0) throw new ArchiveError("Encrypted ARJ members are unsupported");
if ((flags & 0x0c) !== 0) throw new ArchiveError("Multi-volume ARJ members are unsupported");
const packedSize = u32(bytes, block.bodyStart + 12);
const size = u32(bytes, block.bodyStart + 16);
const fileCrc = u32(bytes, block.bodyStart + 20);
const accessMode = u16(bytes, block.bodyStart + 26);
const filename = readCString(
bytes,
block.bodyStart + firstHeaderSize,
block.bodyStart + block.bodySize,
"filename",
);
readCString(bytes, filename.next, block.bodyStart + block.bodySize, "comment");
assertArchivePathBytes(
filename.next - (block.bodyStart + firstHeaderSize) - 1,
"member path",
options.limits.maxPathBytes,
);
const rawPath = normalizeHostPath(filename.value, hostOs);
assertArchivePathString(rawPath, "member path", options.limits.maxPathBytes);View on GitHub (pinned to 9690622007)
Solutions
- Extract the complete volume set with the original ARJ tool (all .arj/.aNN files present) and index the extracted files or the re-merged single archive.
- Reject multi-volume inputs in your pipeline before parsing by pre-checking the main header flags (0x04) and member flags.
- Repackage the data as a single-volume archive if you control the source.
- Use an external ARJ-compatible extractor that supports volumes, then hand the plain files to this library's other readers if applicable.
Example fix
// before
const entries = await readArj(volume1Bytes, options); // throws on spanning member
// after
if (hasArjVolumeFlags(volume1Bytes)) {
const files = await extractAllVolumesWithArjTool(volumeDir);
// index extracted plain files instead
} Defensive patterns
Strategy: validation
Validate before calling
function hasArjVolumeMembers(bytes: Uint8Array): boolean {
return scanArjLocalFlags(bytes).some((flags) => (flags & 0x0c) !== 0);
}
if (hasArjVolumeMembers(bytes)) throw new Error("ARJ members span volumes; extract the full set first"); Type guard
function isSingleVolumeArjMemberFlags(flags: number): boolean {
return (flags & 0x0c) === 0;
} Try / catch
try {
entries = await readArj(source, options);
} catch (e) {
if (e instanceof ArchiveError && e.message === "Multi-volume ARJ members are unsupported") {
return { status: "multi-volume-member", hint: "extract all volumes with the ARJ tool, then index the output" };
}
throw e;
} Prevention
- Reject split archives at ingest (main header flag 0x04 is a cheap early signal).
- Ensure the complete volume set accompanies any multi-volume ARJ before processing.
- Repackage legacy split backups into single archives during migration.
When it happens
Trigger: readArj parses a local header whose flags byte has any of 0x04 or 0x08 set — the member's data continues on the next/previous volume of a split archive.
Common situations: Members split across .arj/.a01/.a02 volumes of a floppy-era backup; indexing only the first volume while the member actually spans volumes.
Related errors
- Multi-volume ARJ archives are unsupported
- ARJ member '${memberPath}' uses unsupported compression meth
- Encrypted ARJ archives are unsupported
- Encrypted ARJ members are unsupported
- Unsupported multi-volume CAB archive (previous/next cabinet
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/207fb30bdc8c2cf9.
Report an issue: GitHub.