can1357/oh-my-pi · error · ArchiveError

ASAR payload is too large to encode safely

Error message

ASAR payload is too large to encode safely

What it means

encodeAsar tracks the running total payload size and requires every member's byteLength, and the cumulative total, to stay within Number.MAX_SAFE_INTEGER (2^53-1). A member whose Uint8Array claims an unsafe size, or whose addition would push the total past that bound, makes offsets unreliable, so the library throws before writing anything.

Source

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

			for (let index = 0; index < parts.length - 1; index++) {
				const part = parts[index]!;
				const existing = directory.files[part];
				if (existing && !("files" in existing)) {
					throw new ArchiveError(
						`ASAR member path '${memberPath}' crosses file '${parts.slice(0, index + 1).join("/")}'`,
					);
				}
				if (!existing) {
					directory.files[part] = { files: Object.create(null) as Record<string, AsarNode> };
				}
				directory = directory.files[part] as AsarDirectoryNode;
			}
			const name = parts.at(-1)!;
			if (directory.files[name]) {
				throw new ArchiveError(`Duplicate or conflicting ASAR member path '${memberPath}'`);
			}
			if (!Number.isSafeInteger(member[1].byteLength) || !Number.isSafeInteger(payloadSize + member[1].byteLength)) {
				throw new ArchiveError("ASAR payload is too large to encode safely");
			}
			directory.files[name] = { size: member[1].byteLength, offset: String(payloadSize) };
			payloads.push(member[1]);
			payloadSize += member[1].byteLength;
		}

		const jsonBytes = ASAR_HEADER_ENCODER.encode(JSON.stringify(root));
		const paddedJsonSize = alignAsarPayload(jsonBytes.byteLength);
		const innerPayloadSize = 4 + paddedJsonSize;
		const headerSize = 4 + innerPayloadSize;
		if (jsonBytes.byteLength > 0xffffffff || headerSize > 0xffffffff) {
			throw new ArchiveError("ASAR header is too large to encode");
		}
		const dataOffset = ASAR_PICKLE_PREFIX_SIZE + headerSize;
		const archiveSize = dataOffset + payloadSize;
		if (!Number.isSafeInteger(archiveSize)) {
			throw new ArchiveError("ASAR archive is too large to encode safely");
		}

View on GitHub (pinned to 9690622007)

Solutions

  1. Split the archive into multiple ASAR files so each stays well under the safe-integer limit.
  2. Verify member contents are real Uint8Array/Blob-backed data with sane byteLength before encoding.
  3. If archiving huge datasets, use chunked on-disk writing instead of one in-memory encode call.
  4. Catch ArchiveError and report the total size; audit the member source for corrupted length metadata.

Example fix

// before
await encodeAsar([...allHugeFiles]); // total payload > 2^53
// after
for (const chunk of partition(allHugeFiles, maxChunkBytes)) {
  await encodeAsar(chunk);
}
Defensive patterns

Strategy: validation

Validate before calling

function assertSafePayload(members) {
  let total = 0;
  for (const [, data] of members) {
    if (!Number.isSafeInteger(data.byteLength)) throw new Error('member has unsafe byteLength');
    total += data.byteLength;
    if (!Number.isSafeInteger(total)) throw new Error('total ASAR payload exceeds safe integer range');
  }
}
assertSafePayload(members);

Type guard

function isEncodableMember(m) {
  return Array.isArray(m) && m.length === 2 &&
    typeof m[0] === 'string' && m[1] instanceof Uint8Array &&
    Number.isSafeInteger(m[1].byteLength);
}

Try / catch

try {
  const archive = await encodeAsar(members);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes('payload is too large')) {
    throw new Error('Split the member set: total payload exceeds safe integer range');
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling encodeAsar/encodeArchive/bytes with a Uint8Array whose byteLength exceeds 2^53-1 (practically impossible from real buffers but possible from fake/hostile objects), or accumulating members whose combined size exceeds Number.MAX_SAFE_INTEGER.

Common situations: Archiving extremely large payloads or unbounded synthetic data in tests; a buggy Uint8Array-like object with a corrupt byteLength; streaming pipelines that lose track of accumulated archive size.

Related errors


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