can1357/oh-my-pi · error · ArchiveError

Invalid RPM package: tag ${tag} is not valid UTF-8

Error message

Invalid RPM package: tag ${tag} is not valid UTF-8

What it means

The parser decodes string tag values with a fatal-mode UTF-8 TextDecoder; invalid byte sequences throw and are rethrown as this ArchiveError. RPM metadata strings should be UTF-8 (traditionally ASCII/Latin-1 in old packages), so non-UTF-8 bytes indicate either a corrupt value or a legacy package with raw 8-bit encoding.

Source

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

	dataSize: number,
	offset: number,
	count: number,
	type: number,
	tag: number,
): string {
	if (type !== RPM_TYPE_STRING || count !== 1) {
		throw new ArchiveError(`Invalid RPM package: tag ${tag} must contain one string`);
	}
	const start = indexSize + offset;
	const limit = indexSize + dataSize;
	let end = start;
	while (end < limit && body[end] !== 0) end++;
	if (end === limit) throw new ArchiveError(`Invalid RPM package: tag ${tag} string is not NUL-terminated`);
	if (end - start > 4096) throw new ArchiveError(`Invalid RPM package: tag ${tag} string is too large`);
	try {
		return UTF8_FATAL_DECODER.decode(body.subarray(start, end));
	} catch {
		throw new ArchiveError(`Invalid RPM package: tag ${tag} is not valid UTF-8`);
	}
}

function parseMainHeader(body: Uint8Array, intro: HeaderIntro): RpmMetadata {
	validateHeaderBody(body, intro, "main");
	const indexSize = intro.indexCount * RPM_INDEX_ENTRY_SIZE;
	if (body.byteLength !== intro.bodySize) throw new ArchiveError("Invalid RPM package: truncated main header");
	const metadata: RpmMetadata = {};
	for (let index = 0; index < intro.indexCount; index++) {
		const recordOffset = index * RPM_INDEX_ENTRY_SIZE;
		const tag = readUInt32BE(body, recordOffset);
		const type = readUInt32BE(body, recordOffset + 4);
		const offset = readUInt32BE(body, recordOffset + 8);
		const count = readUInt32BE(body, recordOffset + 12);
		if (offset > intro.dataSize) throw new ArchiveError(`Invalid RPM package: tag ${tag} points outside header data`);
		if (
			tag !== RPM_TAG_NAME &&
			tag !== RPM_TAG_VERSION &&

View on GitHub (pinned to 9690622007)

Solutions

  1. Rebuild or re-download the package; prefer packages built with modern rpmbuild that emit UTF-8 metadata.
  2. If you control the package, convert its metadata (Summary/Description/Name) to valid UTF-8.
  3. Confirm corruption vs. legacy encoding using `rpm -qp` which may render legacy encodings.
  4. Catch ArchiveError around readRpm and either skip the package or retry with a transcoding preprocessor if you must support legacy packages.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  return await readRpm(source, options);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes("not valid UTF-8")) {
    return rejectPackage("RPM metadata is not UTF-8 (legacy encoding or corruption)");
  }
  throw err;
}

Prevention

When it happens

Trigger: readHeaderString successfully finds a NUL-terminated, <=4096-byte value for a known tag, but UTF8_FATAL_DECODER.decode fails on the bytes — e.g. a NAME containing invalid sequences like 0xFF.

Common situations: Very old RPM packages built with locale-specific encodings (ISO-8859-1 metadata) instead of UTF-8; corruption of string bytes; packages with binary junk injected into metadata fields.

Related errors


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