can1357/oh-my-pi · error · ArchiveError
Invalid ar archive BSD extended name length
Error message
Invalid ar archive BSD extended name length
What it means
For BSD-style extended names ('#1/<len>'), parseHeader extracts the length digits from the raw name field and validates them: all digits, a safe integer, strictly positive, and not larger than the member's physical size (the name is stored at the start of the member data, so it can't exceed it). This first throw fires when the text after '#1/' is not purely digits.
Source
Thrown at packages/utils/src/ar/unix-ar.ts:98
bsdNameLength?: number;
} {
if (
header.byteLength !== HEADER_SIZE ||
header[HEADER_TRAILER_OFFSET] !== 0x60 ||
header[HEADER_TRAILER_OFFSET + 1] !== 0x0a
) {
throw new ArchiveError("Invalid ar archive member header");
}
const rawName = decodeAsciiField(header, 0, NAME_SIZE);
const mtimeSeconds = parseOptionalNumber(decodeAsciiField(header, 16, 12), 10, "modification time");
parseOptionalNumber(decodeAsciiField(header, 28, 6), 10, "user id");
parseOptionalNumber(decodeAsciiField(header, 34, 6), 10, "group id");
const mode = parseOptionalNumber(decodeAsciiField(header, 40, 8), 8, "mode");
const physicalSize = parseRequiredSize(decodeAsciiField(header, 48, 10));
let bsdNameLength: number | undefined;
if (rawName.startsWith("#1/")) {
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 };View on GitHub (pinned to 9690622007)
Solutions
- Confirm the producer is BSD ar and the '#1/' encoding is intended; regenerate with consistent tooling (llvm-ar / GNU ar) for cross-platform compatibility
- Hex-dump the name field (bytes 0-15) and check what follows '#1/'
- Rename files starting with '#1/' in the producer or escape them via the intended encoding
- Ensure the writer stores the 4-byte length in the member data as BSD ar does for #1/ names
Example fix
// before: malformed BSD name field rawName = '#1/ 12' // digits check fails on the space // after: correct BSD form rawName = '#1/12 ' // decoded length digits '12'
Defensive patterns
Strategy: validation
Validate before calling
function bsdNamePrefixIsValid(rawName: string): boolean {
if (!rawName.startsWith('#1/')) return true; // not a BSD long name
return /^\d+$/.test(rawName.slice(3));
}
if (!bsdNamePrefixIsValid(rawNameField)) throw new Error('malformed #1/ BSD name'); Type guard
function isBsdLongNameRef(rawName: string): boolean {
return /^#1\/\d+$/.test(rawName);
} Try / catch
try {
const names = await archive.list();
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('BSD extended name length')) {
// archive mixes BSD naming unexpectedly — inspect with ar t / llvm-ar t
} else throw err;
} Prevention
- Use one ar variant (GNU or BSD) consistently for producing archives
- Don't create files whose names begin with '#1/' unless BSD encoding is intended
- Validate name fields in your writer before serialization
- Test cross-platform archives (macOS BSD ar vs GNU ar) in CI
When it happens
Trigger: Parsing an archive whose member rawName starts with '#1/' followed by non-digit characters — e.g. '#1/abc' or '#1/' with trailing content, or a name coincidentally beginning with '#1/' in a non-BSD archive.
Common situations: Archives from BSD ar (macOS) parsed where the GNU convention was expected; custom writers emitting '#1/' prefixes incorrectly; filenames that literally start with '#1/' written without BSD long-name encoding.
Related errors
- Invalid ar archive empty BSD extended name
- Invalid ar archive member name '${reference}'
- Invalid ar archive ${field}
- Invalid ar archive member size
- Invalid ar archive member header
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ffa9c88dd2cb30b2.
Report an issue: GitHub.