can1357/oh-my-pi · error · ArchiveError
Unpacked ASAR file '${label}' size differs from its archive
Error message
Unpacked ASAR file '${label}' size differs from its archive header (${stat.size} != ${this.#size} bytes) What it means
Thrown when the unpacked sidecar file exists and is a regular file, but its size on disk differs from the `size` recorded for that member in the ASAR header. The archive format relies on the header being authoritative, so the mismatch makes the payload untrustworthy.
Source
Thrown at packages/utils/src/ar/asar.ts:163
}
async read(size: number, memberPath: string): Promise<Uint8Array> {
const label = formatArchivePathForError(memberPath);
if (size !== this.#size) {
throw new ArchiveError(`ASAR member '${label}' has an inconsistent size`);
}
if (!this.#filePath) {
throw new ArchiveError(`Archive file '${label}' is unpacked and requires a filesystem-backed ASAR archive`);
}
const file = Bun.file(this.#filePath);
const stat = await file.stat().catch(() => {
throw new ArchiveError(`Unpacked ASAR file '${label}' was not found`);
});
if (stat.isDirectory()) {
throw new ArchiveError(`Unpacked ASAR file '${label}' is a directory`);
}
if (stat.size !== this.#size) {
throw new ArchiveError(
`Unpacked ASAR file '${label}' size differs from its archive header (${stat.size} != ${this.#size} bytes)`,
);
}
let bytes: Uint8Array;
try {
bytes = await file.bytes();
} catch (error) {
throw new ArchiveError(`Failed to read unpacked ASAR file '${label}': ${describeError(error)}`);
}
if (bytes.byteLength !== this.#size) {
throw new ArchiveError(`Unpacked ASAR file '${label}' changed while being read`);
}
verifyIntegrity(bytes, this.#integrity, memberPath);
return bytes;
}
}
async function readAsarIndex(source: ByteSource, options: FormatReadOptions): Promise<ArchiveIndexEntry[]> {View on GitHub (pinned to 9690622007)
Solutions
- Restore the unpacked file to the exact content packed into the ASAR (re-extract from the original source)
- Regenerate the ASAR header (repack) if the unpacked file was intentionally updated
- Re-run your packaging tool so .asar and .unpacked are produced from the same build
Example fix
npx asar extract app.asar restore-dir/ # restore expected sidecar contents # then repack: npx asar pack app/ app.asar --unpack-dir assets
Defensive patterns
Strategy: validation
Validate before calling
const st = await Bun.file(sidecar).stat();
if (st.size !== entry.size) throw new Error(`sidecar size ${st.size} != header ${entry.size} for ${entry.path}`); Try / catch
try { return await readMember(entry); } catch (e) { if (e instanceof ArchiveError && e.message.includes("size differs from its archive header")) { /* re-extract sidecar or repack archive */ } throw e; } Prevention
- Never edit files inside .unpacked after packaging; rebuild instead
- Repack both .asar and .unpacked in the same build step
- Compare sizes of all sidecars against the header as a post-build check
When it happens
Trigger: Reading an unpacked member whose sidecar file was modified, truncated, or replaced since the ASAR was packed (stat.size !== header-declared size).
Common situations: Files updated in place in .unpacked after packaging; partial downloads or interrupted copies; repacking the .asar without regenerating the .unpacked sidecars; editors/IDEs rewriting files on save.
Related errors
- Archive file '${label}' is unpacked and requires a filesyste
- Unpacked ASAR file '${label}' was not found
- Embedded addon size mismatch for ${filename}: expected ${fil
- ASAR member '${formatArchivePathForError(memberPath)}' faile
- ASAR member '${formatArchivePathForError(memberPath)}' has a
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d36928cafd04bbde.
Report an issue: GitHub.