can1357/oh-my-pi · error · ArchiveError

RPM package '${identity}' has an invalid uncompressed CPIO p

Error message

RPM package '${identity}' has an invalid uncompressed CPIO payload

What it means

The payload was classified as uncompressed ('none'), but sniffCpio does not recognize the bytes as a CPIO archive (newc/old ascii-style magic), so the reader rejects them instead of returning a bogus entry list. An RPM with method 'none' must contain a raw CPIO payload.

Source

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

	switch (method) {
		case "gzip":
		case "gz":
			return gzipDecompress(payload, maxOutput);
		case "bzip2":
		case "bzip":
			return bzip2Decompress(payload, maxOutput);
		case "xz":
			return xzDecompress(payload, maxOutput);
		case "zstd":
		case "zstdio":
			return zstdDecompress(payload, maxOutput);
		case "lzma":
			if (!sniffLzmaAlone(payload)) throw new ArchiveError(`RPM package '${identity}' has a malformed LZMA payload`);
			return lzmaAloneDecompress(payload, maxOutput);
		case "none":
			if (!sniffCpio(payload))
				throw new ArchiveError(`RPM package '${identity}' has an invalid uncompressed CPIO payload`);
			return payload;
		default:
			throw new ArchiveError(`RPM package '${identity}' uses unsupported payload compressor '${method}'`);
	}
}

async function readRpmArchive(source: ByteSource, options: FormatReadOptions): Promise<ArchiveIndexEntry[]> {
	const initial = await readExact(source, 0, RPM_LEAD_SIZE + RPM_HEADER_INTRO_SIZE, "lead and signature header");
	if (!sniffRpm(initial)) throw new ArchiveError("Invalid RPM package: bad lead magic");
	const major = initial[4]!;
	const packageType = (initial[6]! << 8) | initial[7]!;
	if (major < 3 || packageType > 1) throw new ArchiveError("Unsupported RPM package lead version or type");
	const signatureType = (initial[78]! << 8) | initial[79]!;
	if (signatureType !== RPM_SIGNATURE_TYPE_HEADER) {
		throw new ArchiveError(`Unsupported RPM signature type ${signatureType}; only header signatures are supported`);
	}
	const leadNameEnd = initial.subarray(10, 76).indexOf(0);
	const leadNameBytes = initial.subarray(10, leadNameEnd < 0 ? 76 : 10 + leadNameEnd);

View on GitHub (pinned to 9690622007)

Solutions

  1. Rebuild the RPM so its uncompressed payload is a valid CPIO archive (rpmbuild uses cpio internally; avoid hand-rolled payload writers).
  2. Check the payload magic bytes with a hexdump to identify the actual format.
  3. Extract with rpm2cpio | cpio as a fallback and confirm the package itself is valid.
  4. Re-download and checksum-verify — corruption can also scramble a valid CPIO payload.
Defensive patterns

Strategy: validation

Validate before calling

async function startsWithCpioMagic(path: string, payloadOffset: number): Promise<boolean> {
  const b = new Uint8Array(await Bun.file(path).slice(payloadOffset, payloadOffset + 6).arrayBuffer());
  const s = new TextDecoder().decode(b);
  return s.startsWith('070701') || s.startsWith('070707');
}

Type guard

function looksLikeCpio(head: Uint8Array): boolean {
  const ascii = String.fromCharCode(...head.slice(0, 6));
  return ascii === '070701' || ascii === '070707';
}

Try / catch

try {
  return await readRpm(path);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes('invalid uncompressed CPIO payload')) {
    throw new Error('RPM payload is neither compressed nor a valid CPIO archive — package corrupt');
  }
  throw err;
}

Prevention

When it happens

Trigger: decompressPayload hits case "none" and sniffCpio(payload) returns false — i.e. the payload lacks the CPIO magic ('070701'/'070707') despite the compression sniff concluding 'none'.

Common situations: Packages produced by custom build tooling that wrote a non-CPIO payload without compression, corrupted files where payload bytes were altered, or payloads in cpio variants this sniffer does not recognize.

Related errors


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