can1357/oh-my-pi · error · ArchiveError

ASAR member '${formatArchivePathForError(memberPath)}' has a

Error message

ASAR member '${formatArchivePathForError(memberPath)}' has an inconsistent size

What it means

The packed ASAR member source records the member's size from the archive header. When read(size, memberPath) is called with a requested size that differs from the header-recorded size, the internal offsets and the caller's expectation disagree — the caller would read the wrong byte range — so the reader refuses rather than returning wrong data.

Source

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

	}
}

class PackedAsarMemberSource implements MemberSource {
	readonly #source: ByteSource;
	readonly #offset: number;
	readonly #size: number;
	readonly #integrity?: AsarIntegrity;

	constructor(source: ByteSource, offset: number, size: number, integrity: AsarIntegrity | undefined) {
		this.#source = source;
		this.#offset = offset;
		this.#size = size;
		this.#integrity = integrity;
	}

	async read(size: number, memberPath: string): Promise<Uint8Array> {
		if (size !== this.#size) {
			throw new ArchiveError(`ASAR member '${formatArchivePathForError(memberPath)}' has an inconsistent size`);
		}
		let bytes: Uint8Array;
		try {
			bytes = await this.#source.read(this.#offset, this.#offset + this.#size);
		} catch (error) {
			if (error instanceof ArchiveError) throw error;
			throw new ArchiveError(
				`Failed to read ASAR member '${formatArchivePathForError(memberPath)}': ${describeError(error)}`,
			);
		}
		if (bytes.byteLength !== this.#size) {
			throw new ArchiveError(`ASAR member '${formatArchivePathForError(memberPath)}' is truncated`);
		}
		verifyIntegrity(bytes, this.#integrity, memberPath);
		return bytes;
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Regenerate the ASAR with the official asar tool so header sizes and pickles are consistent.
  2. Audit any custom ASAR-parsing code: the size passed to read must come from the same header entry (offset+size pair), not a separately parsed pickle.
  3. Validate the archive structurally (header pickle sizes vs. member entries) before reading members and reject inconsistent files early.
  4. Verify the file is not truncated/corrupted by comparing whole-file size against the header's expected total.

Example fix

// before
const bytes = await source.read(someOtherLength, path); // mismatch → throws
// after
const entry = headerEntryFor(path);
const bytes = await source.read(entry.size, path); // always the header-recorded size
Defensive patterns

Strategy: validation

Validate before calling

// Before reading, confirm every member's size pickle and header entry agree.
function assertAsarSizesConsistent(header: AsarHeader): void {
	for (const [p, entry] of Object.entries(header.files)) {
		if (!Number.isSafeInteger(entry.size) || entry.size < 0 || entry.offset + entry.size > header.totalSize) {
			throw new Error(`ASAR header entry for '${p}' has an inconsistent size`);
		}
	}
}

Type guard

function hasConsistentMemberSize(entry: { offset: number; size: number }, totalSize: number): boolean {
	return Number.isSafeInteger(entry.size) && entry.size >= 0 && entry.offset + entry.size <= totalSize;
}

Try / catch

try {
	const bytes = await member.read(size, path);
} catch (e) {
	if (e instanceof ArchiveError && e.message.includes("has an inconsistent size")) {
		throw new Error(`ASAR header/data out of sync for '${path}'; repack the archive`);
	}
	throw e;
}

Prevention

When it happens

Trigger: read() on a PackedAsarMemberSource with the size argument (derived by the caller from a pickle/header length field) not equal to the member's #size recorded in the ASAR header — inconsistent size pickles or a caller using the wrong length source.

Common situations: Hand-crafted or third-party-written ASAR files where the size pickle and header entry disagree; bugs in code that manually parses the ASAR header and passes the wrong length; corruption of the size fields.

Related errors


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