can1357/oh-my-pi · error · ArchiveError

error instanceof Error ? error.message : String(error)

Error message

error instanceof Error ? error.message : String(error)

What it means

readRpm wraps readRpmArchive: any exception that is not already an ArchiveError (I/O failures, parse errors from helpers, out-of-memory from limits, etc.) is converted into an ArchiveError whose message is the original error's message. The literal shown is the expression used to build that message, so the surfaced text is whatever the underlying throw produced.

Source

Thrown at packages/utils/src/ar/rpm.ts:313

		throw new ArchiveError(`RPM package '${identity}' uses unsupported payload format '${metadata.payloadFormat}'`);
	}

	const payloadOffset = mainHeaderOffset + mainIntro.totalSize;
	const payloadSize = source.size - payloadOffset;
	assertInMemorySize(payloadSize, options.limits);
	const payload = await readExact(source, payloadOffset, source.size, "payload");
	const cpio = await decompressPayload(payload, metadata, identity, options.limits.maxInMemorySize);
	assertInMemorySize(cpio.byteLength, options.limits);
	return readCpioEntriesFromBuffer(cpio, options);
}

/** Read an RPM lead, headers, compressed payload, and its contained CPIO entries. */
export const readRpm: FormatReader = async (source, options) => {
	try {
		return await readRpmArchive(source, options);
	} catch (error) {
		if (error instanceof ArchiveError) throw error;
		throw new ArchiveError(error instanceof Error ? error.message : String(error));
	}
};

/** Detect the four-byte RPM package lead magic. */
export function sniffRpm(bytes: Uint8Array): boolean {
	return bytes.byteLength >= 4 && bytes[0] === 0xed && bytes[1] === 0xab && bytes[2] === 0xee && bytes[3] === 0xdb;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Catch ArchiveError around readRpm and inspect error.message to see the wrapped root cause.
  2. Verify the input source is a complete RPM (check magic 0xEDABEEDB and file size) before parsing.
  3. Ensure the source stream (file, buffer) is readable and not closed/truncated mid-read.

Example fix

// before
const entries = await readRpm(source);
// after
try {
  const entries = await readRpm(source);
} catch (err) {
  if (err instanceof ArchiveError) {
    console.error("RPM parse failed:", err.message); // may be a wrapped root cause
  } else throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify RPM magic before reading
function looksLikeRpm(bytes: Uint8Array): boolean {
  return bytes.byteLength >= 4 && bytes[0] === 0xed && bytes[1] === 0xab && bytes[2] === 0xee && bytes[3] === 0xdb;
}

Type guard

function isArchiveError(err: unknown): err is ArchiveError {
  return err instanceof ArchiveError;
}

Try / catch

try {
  const entries = await readRpm(source);
} catch (err) {
  if (isArchiveError(err)) {
    logger.error("RPM read failed", { message: err.message }); // message may be a wrapped root cause
  } else throw err;
}

Prevention

When it happens

Trigger: Any non-ArchiveError throw inside readRpmArchive or its helpers: truncated reads from readExact, Uint8Array bounds violations, RangeError from size limit assertions, JSON/type errors in header parsing — all funnel through this wrapper.

Common situations: Reading from a short/closed stream that fails mid-read; feeding a non-RPM file that sniffs past magic but fails header validation; integer overflow / RangeError on absurd header sizes.

Related errors


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