can1357/oh-my-pi · error · ArchiveError
Archive file '${label}' is unpacked and requires a filesyste
Error message
Archive file '${label}' is unpacked and requires a filesystem-backed ASAR archive What it means
Thrown by UnpackedAsarMemberSource.read when an ASAR entry is flagged `unpacked: true` but no filesystem path could be resolved for its sidecar file. Unpacked members live in `<archive>.unpacked/` next to the ASAR file, and their absolute path can only be computed when the archive was opened via `options.archivePath`. Reading such a member from an in-memory or stream-backed source is impossible.
Source
Thrown at packages/utils/src/ar/asar.ts:153
class UnpackedAsarMemberSource implements MemberSource {
readonly #filePath?: string;
readonly #size: number;
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)}`);View on GitHub (pinned to 9690622007)
Solutions
- Open the archive with its real filesystem path so options.archivePath is set and `<asar>.unpacked/` sidecars can be resolved
- Ship the `<archive>.unpacked/` directory alongside the .asar file when distributing
- Repack the ASAR without unpacked files (no `unpack` options) if only the single .asar will be available
Example fix
// before
const archive = await readArchive(await Bun.file(app.asar).bytes());
// after
const archive = await readArchiveFromFile("/app/resources/app.asar", { archivePath: "/app/resources/app.asar" }); Defensive patterns
Strategy: fallback
Validate before calling
if (entry.storage?.source instanceof UnpackedAsarMemberSource) {
// only safe when archive was opened with archivePath
if (!options.archivePath) throw new Error("unpacked member requires filesystem-backed archive");
} Type guard
const canReadUnpacked = (entry) => !isUnpacked(entry) || Boolean(options.archivePath);
Try / catch
try { return await readMember(entry); } catch (e) { if (String(e.message).includes("requires a filesystem-backed ASAR")) return readUnpackedFromDisk(`${asarPath}.unpacked/${entry.path}`); throw e; } Prevention
- Open ASAR archives by file path (with archivePath) whenever unpacked members are expected
- Distribute the .unpacked directory together with the .asar
- Prefer fully-packed archives when shipping a single file
When it happens
Trigger: Reading an unpacked member of an ASAR that was opened from a stream or memory buffer (no archivePath), so UnpackedAsarMemberSource was constructed with filePath === undefined.
Common situations: Opening a downloaded or bundled .asar from bytes and then reading a member that the packager marked unpacked (common with Electron apps using asar.unpack); embedding ASAR parsing where only raw bytes are available.
Related errors
- Unpacked ASAR file '${label}' was not found
- Unpacked ASAR file '${label}' is a directory
- Unpacked ASAR file '${label}' size differs from its archive
- Failed to read unpacked ASAR file '${label}': ${describeErro
- Unpacked ASAR file '${label}' changed while being read
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3da655cb863a6002.
Report an issue: GitHub.