can1357/oh-my-pi · error · ArchiveError

Failed to encode ASAR archive: ${describeError(error)}

Error message

Failed to encode ASAR archive: ${describeError(error)}

What it means

encodeAsar wraps its whole encoding pipeline in a try/catch: any unexpected exception (JSON.stringify failure, TextEncoder issues, bugs in member handling) that is not already an ArchiveError is rethrown as ArchiveError(`Failed to encode ASAR archive: ${describeError(error)}`). ArchiveErrors thrown inside (size limits, path conflicts, allocation failures) pass through unchanged with their specific messages.

Source

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

		try {
			output = new Uint8Array(archiveSize);
		} catch {
			throw new ArchiveError("ASAR archive is too large to encode in memory");
		}
		writeUInt32LE(output, 0, 4);
		writeUInt32LE(output, 4, headerSize);
		writeUInt32LE(output, 8, innerPayloadSize);
		writeUInt32LE(output, 12, jsonBytes.byteLength);
		output.set(jsonBytes, ASAR_JSON_OFFSET);
		let offset = dataOffset;
		for (const payload of payloads) {
			output.set(payload, offset);
			offset += payload.byteLength;
		}
		return output;
	} catch (error) {
		if (error instanceof ArchiveError) throw error;
		throw new ArchiveError(`Failed to encode ASAR archive: ${describeError(error)}`);
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the inner describeError message to identify the original failure cause.
  2. Validate members before calling: each payload must be a Uint8Array and paths must be unique, non-conflicting strings.
  3. If the message masks an allocation failure, treat it like the 'too large to encode in memory' case and shrink the payload.
  4. Upgrade/report: if the underlying cause looks like a library bug, reproduce with the original error enabled by catching before this wrapper.

Example fix

// before
const members = new Map([["a.txt", "not-a-uint8array"]]); // string payload slips through untyped code
encodeAsar(members); // -> Failed to encode ASAR archive: ...
// after
const members = new Map([["a.txt", new TextEncoder().encode("hello")]]);
const payloads: Array<[string, Uint8Array]> = [...members].filter(([, v]) => v instanceof Uint8Array);
encodeAsar(payloads);
Defensive patterns

Strategy: try-catch

Validate before calling

function validateMembers(members) {
  for (const [path, payload] of members) {
    if (typeof path !== "string" || path.length === 0) throw new Error(`bad member path: ${String(path)}`);
    if (!(payload instanceof Uint8Array)) throw new Error(`member '${path}' is not a Uint8Array`);
  }
}

Type guard

function isAsarMember(v) {
  return Array.isArray(v) && typeof v[0] === "string" && v[1] instanceof Uint8Array;
}

Try / catch

try {
  return encodeAsar(members);
} catch (err) {
  if (err instanceof ArchiveError) {
    if (err.message.startsWith("Failed to encode ASAR archive")) {
      logger.error("asar encode failed", { cause: err.message });
    }
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: Any non-ArchiveError exception inside encodeAsar — most commonly JSON.stringify throwing on circular structures if a custom root was constructed, or an underlying engine error during the output.set copies; i.e. anything that bypasses the pre-validated fast paths.

Common situations: Malformed member lists (non-Uint8Array payloads from an untyped call site), unexpected engine failures mid-copy on very large archives, or library version changes that altered internal invariants — surfaced here because the catch-all converts them into a uniform ArchiveError.

Related errors


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