can1357/oh-my-pi · error · ArchiveError
Invalid ar archive empty BSD extended name
Error message
Invalid ar archive empty BSD extended name
What it means
decodeBsdName extracts the BSD extended name from the member data up to the first NUL byte and throws if the resulting name is empty (byte length 0) — i.e. the name region starts with a NUL or has no bytes. Zero-length names are rejected earlier via the '#1/0' range check, so this fires when stored name data is empty despite a claimed positive length.
Source
Thrown at packages/utils/src/ar/unix-ar.ts:115
const encodedLength = rawName.slice(3);
if (!/^\d+$/.test(encodedLength)) throw new ArchiveError("Invalid ar archive BSD extended name length");
bsdNameLength = Number.parseInt(encodedLength, 10);
if (!Number.isSafeInteger(bsdNameLength) || bsdNameLength <= 0 || bsdNameLength > physicalSize) {
throw new ArchiveError("Invalid ar archive BSD extended name length");
}
}
return { rawName, physicalSize, mtimeSeconds, mode, bsdNameLength };
}
function decodeName(bytes: Uint8Array, limits: ArchiveLimits): string {
assertArchivePathBytes(bytes.byteLength, "member path", limits.maxPathBytes);
return UTF8_DECODER.decode(bytes);
}
function decodeBsdName(bytes: Uint8Array, limits: ArchiveLimits): { name: string; byteLength: number } {
const nul = bytes.indexOf(0);
const nameBytes = nul >= 0 ? bytes.subarray(0, nul) : bytes;
if (nameBytes.byteLength === 0) throw new ArchiveError("Invalid ar archive empty BSD extended name");
return { name: decodeName(nameBytes, limits), byteLength: nameBytes.byteLength };
}
function shortName(rawName: string): string {
if (rawName === "/" || rawName === "//" || rawName === "/SYM64/") return rawName;
return rawName.endsWith("/") ? rawName.slice(0, -1) : rawName;
}
function resolveLongName(
reference: string,
table: Uint8Array,
limits: ArchiveLimits,
): { name: string; byteLength: number } {
const offsetText = reference.slice(1);
if (!/^\d+$/.test(offsetText)) throw new ArchiveError(`Invalid ar archive member name '${reference}'`);
const offset = Number.parseInt(offsetText, 10);
if (!Number.isSafeInteger(offset) || offset < 0 || offset >= table.byteLength) {
throw new ArchiveError(`Invalid ar archive long-name offset '${reference}'`);View on GitHub (pinned to 9690622007)
Solutions
- Verify the producer writes the name bytes (length includes name plus NUL padding to even size) immediately at the start of member data
- Hex-dump the first bytes of the member data; the filename should appear right after the header
- Regenerate with BSD ar / llvm-ar
- Use plain ASCII member names if the producer mishandles multibyte names
Example fix
// before: length declared, name bytes missing memberData = new Uint8Array(4); // padding only // after: name + NUL, padded to even const raw = Buffer.concat([Buffer.from(name), Buffer.alloc(1)]); const data = raw.byteLength % 2 ? Buffer.concat([raw, Buffer.alloc(1)]) : raw;
Defensive patterns
Strategy: validation
Validate before calling
function bsdNameDataPresent(memberData: Uint8Array): boolean {
const nul = memberData.indexOf(0);
const nameBytes = nul >= 0 ? memberData.subarray(0, nul) : memberData;
return nameBytes.byteLength > 0;
}
// check on raw member bytes before handing to the parser Type guard
function hasNonEmptyName(data: Uint8Array): boolean {
return data.byteLength > 0 && data[0] !== 0;
} Try / catch
try {
await archive.extract(dest);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('empty BSD extended name')) {
// member data starts with NUL — regenerate archive with BSD ar
} else throw err;
} Prevention
- Writers must emit name bytes immediately after the header for #1/ members
- NUL-terminate and pad the name to even byte length
- Round-trip parse archives right after writing them
- Avoid tools that rewrite member payloads without preserving name data
When it happens
Trigger: Parsing a BSD '#1/<len>' member whose data begins with 0x00, or whose length refers only to padding bytes, reached through the header decode path during listing/extraction.
Common situations: Custom BSD-style writers that declare a length but forget to write the name bytes; archives where UTF-8 name bytes were stripped; corruption zeroing the head of the member data.
Related errors
- Invalid ar archive BSD extended name length
- Invalid ar archive ${field}
- Invalid ar archive member size
- Invalid ar archive member header
- Invalid ar archive member name '${reference}'
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2fdc4412428d92be.
Report an issue: GitHub.