can1357/oh-my-pi · error · ArchiveError
Duplicate or conflicting ASAR member path '${memberPath}'
Error message
Duplicate or conflicting ASAR member path '${memberPath}' What it means
encodeAsar rejects a member whose full path (after normalization) is already present in the tree, whether as an exact duplicate or as a node of the opposite kind (file vs directory). The library requires every member path to be unique so the JSON header stays unambiguous. The thrown message includes the offending memberPath.
Source
Thrown at packages/utils/src/ar/asar.ts:437
const memberPath = writerPath(member[0]);
const parts = memberPath.split("/");
let directory = root;
for (let index = 0; index < parts.length - 1; index++) {
const part = parts[index]!;
const existing = directory.files[part];
if (existing && !("files" in existing)) {
throw new ArchiveError(
`ASAR member path '${memberPath}' crosses file '${parts.slice(0, index + 1).join("/")}'`,
);
}
if (!existing) {
directory.files[part] = { files: Object.create(null) as Record<string, AsarNode> };
}
directory = directory.files[part] as AsarDirectoryNode;
}
const name = parts.at(-1)!;
if (directory.files[name]) {
throw new ArchiveError(`Duplicate or conflicting ASAR member path '${memberPath}'`);
}
if (!Number.isSafeInteger(member[1].byteLength) || !Number.isSafeInteger(payloadSize + member[1].byteLength)) {
throw new ArchiveError("ASAR payload is too large to encode safely");
}
directory.files[name] = { size: member[1].byteLength, offset: String(payloadSize) };
payloads.push(member[1]);
payloadSize += member[1].byteLength;
}
const jsonBytes = ASAR_HEADER_ENCODER.encode(JSON.stringify(root));
const paddedJsonSize = alignAsarPayload(jsonBytes.byteLength);
const innerPayloadSize = 4 + paddedJsonSize;
const headerSize = 4 + innerPayloadSize;
if (jsonBytes.byteLength > 0xffffffff || headerSize > 0xffffffff) {
throw new ArchiveError("ASAR header is too large to encode");
}
const dataOffset = ASAR_PICKLE_PREFIX_SIZE + headerSize;
const archiveSize = dataOffset + payloadSize;View on GitHub (pinned to 9690622007)
Solutions
- Deduplicate members by normalized path before calling encodeAsar, keeping the last (or intended) entry.
- Fix overlapping glob/include patterns so each file is collected exactly once.
- If a directory-vs-file conflict is intended, rename one of the paths.
- Catch ArchiveError and log the duplicated memberPath to identify which collection step produced the duplicate.
Example fix
// before
const members = [...glob('**/*'), ...glob('*.txt')]; // a.txt collected twice
// after
const byPath = new Map(members);
const unique = [...byPath.entries()]; // last entry wins Defensive patterns
Strategy: validation
Validate before calling
function dedupeMembers(members) {
const byPath = new Map();
for (const m of members) {
const key = m[0].replace(/\\/g, '/');
if (byPath.has(key)) throw new Error(`duplicate ASAR member '${key}'`);
byPath.set(key, m);
}
return [...byPath.values()];
}
const unique = dedupeMembers(members); Try / catch
try {
const archive = await encodeAsar(members);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('Duplicate or conflicting ASAR member')) {
console.error(`Duplicate path in member list: ${err.message}`);
// fall back to a deduped retry
return encodeAsar(dedupeMembers(members));
}
throw err;
} Prevention
- Deduplicate members by normalized path before every encode call.
- Audit glob patterns for overlaps ('**/*' vs '*.txt').
- Use case-normalized keys when merging member lists from case-insensitive filesystems.
- When merging archives, drop or rename shared entries explicitly.
When it happens
Trigger: Passing the same path twice in the members iterable to encodeAsar/encodeArchive/bytes (e.g. ['a.txt', b1] and ['a.txt', b2]), or a path that was already created as a directory by a longer member, e.g. ['a/b', x] followed by ['a', y].
Common situations: Accidentally including a file twice from overlapping glob patterns (e.g. '**/*' plus '*.txt'); concatenating member lists from two archives that share entries; case-insensitive filesystems where 'Readme.md' and 'readme.md' are the same file but produce distinct keys on some platforms.
Related errors
- ASAR member '${formatArchivePathForError(memberPath)}' has a
- ASAR member path '${memberPath}' crosses file '${parts.slice
- RPC host tool names must be unique
- Duplicate rewrite pattern: ${pat}
- import_all: duplicate id ${item.id} in the imported batch. D
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/dc92763d433fede5.
Report an issue: GitHub.