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
- Catch ArchiveError around readRpm and inspect error.message to see the wrapped root cause.
- Verify the input source is a complete RPM (check magic 0xEDABEEDB and file size) before parsing.
- 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
- Sniff the 0xEDABEEDB magic before calling readRpm
- Ensure the source stream is fully readable and sized before parsing
- Catch ArchiveError, not bare Error — non-ArchiveError throws get re-wrapped
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
- Failed to read ASAR member '${formatArchivePathForError(memb
- ${error instanceof Error ? error.message : String(error)}
- Invalid RPM package: truncated ${what}
- Invalid RPM package: corrupt ${what} header magic
- Invalid RPM package: corrupt ${what} header reserved bytes
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/a66d35d2c31bb2f6.
Report an issue: GitHub.