can1357/oh-my-pi · error · ArchiveError

Unpacked ASAR file '${label}' was not found

Error message

Unpacked ASAR file '${label}' was not found

What it means

Thrown when the unpacked sidecar file for an ASAR member (computed as `<archivePath>.unpacked/<member path>`) does not exist on disk — Bun.file().stat() rejected. The header says the member is unpacked, but the corresponding external file is absent.

Source

Thrown at packages/utils/src/ar/asar.ts:157

	readonly #integrity?: AsarIntegrity;

	constructor(filePath: string | undefined, size: number, integrity: AsarIntegrity | undefined) {
		this.#filePath = filePath;
		this.#size = size;
		this.#integrity = integrity;
	}

	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`);
		}

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the `<name>.asar.unpacked/` directory exists next to the archive and contains the member path
  2. Fix your deployment/copy step to include the .unpacked directory (e.g. `cp -r app.asar*` instead of only app.asar)
  3. Repack the archive with the file packed inside if the sidecar layout is not wanted

Example fix

// before
cp app.asar /deploy/app.asar
// after
cp -r app.asar app.asar.unpacked /deploy/
Defensive patterns

Strategy: try-catch

Validate before calling

const sidecar = `${asarPath}.unpacked/${entry.path}`;
if (entry.unpacked && !(await Bun.file(sidecar).exists())) throw new Error(`missing sidecar: ${sidecar}`);

Try / catch

try { return await readMember(entry); } catch (e) { if (e instanceof ArchiveError && e.message.includes("was not found")) { console.error(`Missing .unpacked sidecar for ${entry.path}; reinstall the package`); } throw e; }

Prevention

When it happens

Trigger: Reading an unpacked ASAR member whose `<asar>.unpacked/...` counterpart is missing; distributing the .asar without its .unpacked directory; the unpacked file was deleted or renamed.

Common situations: Incomplete app deployments that copy app.asar but not app.asar.unpacked; build pipelines stripping the sidecar directory; antivirus or cleanup jobs deleting files; wrong archivePath passed so the sidecar path resolves elsewhere.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f2550abf55df8447. Report an issue: GitHub.