can1357/oh-my-pi · error · ArchiveError

Archive ${field} exceeds ${maxPathBytes} bytes

Error message

Archive ${field} exceeds ${maxPathBytes} bytes

What it means

assertArchivePathBytes rejected a member path or link target whose UTF-8 byte length exceeds the configured per-entry path limit. Each format reader (ARJ, ASAR, CAB, CPIO, Rock Ridge merge, link-target builders) enforces this ceiling to prevent resource exhaustion and absurd path names. The message names the field and the byte limit.

Source

Thrown at packages/utils/src/ar/paths.ts:63

/** Clamp an attacker-controlled path to a short preview for error messages. */
export function formatArchivePathForError(value: string): string {
	if (Buffer.byteLength(value, "utf-8") <= PATH_ERROR_PREVIEW_BYTES) return value;

	let end = 0;
	let size = 0;
	for (const char of value) {
		const charSize = Buffer.byteLength(char, "utf-8");
		if (size + charSize > PATH_ERROR_PREVIEW_BYTES - 3) break;
		end += char.length;
		size += charSize;
	}
	return `${value.slice(0, end)}...`;
}

/** Reject a member path/link target longer than `maxPathBytes`. */
export function assertArchivePathBytes(size: number, field: string, maxPathBytes: number): void {
	if (size > maxPathBytes) {
		throw new ArchiveError(`Archive ${field} exceeds ${maxPathBytes} bytes`);
	}
}

/** {@link assertArchivePathBytes} for an already-decoded string. */
export function assertArchivePathString(value: string, field: string, maxPathBytes: number): void {
	assertArchivePathBytes(Buffer.byteLength(value, "utf-8"), field, maxPathBytes);
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Raise the path-bytes limit in the options you pass (limits.maxPathBytes or the relevant ArchiveLimits field) to accommodate the archive.
  2. Repack the archive with shorter member paths (flatten directories, hash-shrink names).
  3. Identify the offending entry via the archive index and remove it before processing.
  4. Keep the default limits if the archive is untrusted — a huge path often signals a fuzzed or hostile input.

Example fix

// before
const reader = await openArchive(input); // default path-bytes limit
// after
const reader = await openArchive(input, { limits: { maxPathBytes: 4096 } });
Defensive patterns

Strategy: try-catch

Validate before calling

const MAX = 4096;
const reader = await openArchive(src);
for (const e of reader.indexEntries()) {
  if (Buffer.byteLength(e.path, "utf8") > MAX) throw new Error(`path too long: ${e.path.slice(0, 64)}...`);
}

Try / catch

try {
  await extractArchive(src, dest);
} catch (err) {
  if (err instanceof ArchiveError && /exceeds \d+ bytes/.test(err.message)) {
    // retry with a higher limits.maxPathBytes or skip the entry
  }
  throw err;
}

Prevention

When it happens

Trigger: Reading any archive whose entry name or symlink target is longer than maxPathBytes — e.g. a tar member name over the limit passed via FormatReadOptions.limits, or a Rock Ridge NM field exceeding the ceiling during metadata merge.

Common situations: Archives containing machine-generated hash-named paths (node_modules, build caches) with extremely deep/long names; fuzzed or corrupt archives with gigantic name fields; callers lowering maxPathBytes below what a legitimate archive needs.

Related errors


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