can1357/oh-my-pi · error · ArchiveError
Invalid RPM package: null tag ${tag} has values
Error message
Invalid RPM package: null tag ${tag} has values What it means
ArchiveError thrown by validateHeaderBody() when an index entry has type 0 (RPM NULL type) but a non-zero count. Per the RPM format, NULL entries carry no data, so count must be 0; this enforces that invariant while walking the header index.
Source
Thrown at packages/utils/src/ar/rpm.ts:89
function validateHeaderBody(body: Uint8Array, intro: HeaderIntro, what: string): void {
const indexSize = intro.indexCount * RPM_INDEX_ENTRY_SIZE;
if (body.byteLength !== intro.bodySize) throw new ArchiveError(`Invalid RPM package: truncated ${what} header`);
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`);
const remaining = intro.dataSize - offset;
let elementSize = 0;
if (type === 1 || type === 2 || type === 7) elementSize = 1;
else if (type === 3) elementSize = 2;
else if (type === 4) elementSize = 4;
else if (type === 5) elementSize = 8;
else if (type === 0) {
if (count !== 0) throw new ArchiveError(`Invalid RPM package: null tag ${tag} has values`);
continue;
} else if (type === RPM_TYPE_STRING || type === 8 || type === 9) {
const stringCount = type === RPM_TYPE_STRING ? 1 : count;
if (type === RPM_TYPE_STRING && count !== 1) {
throw new ArchiveError(`Invalid RPM package: string tag ${tag} has an invalid count`);
}
if (stringCount > remaining) {
throw new ArchiveError(`Invalid RPM package: string tag ${tag} exceeds header data`);
}
let cursor = indexSize + offset;
const limit = indexSize + intro.dataSize;
for (let stringIndex = 0; stringIndex < stringCount; stringIndex++) {
while (cursor < limit && body[cursor] !== 0) cursor++;
if (cursor === limit) {
throw new ArchiveError(`Invalid RPM package: string tag ${tag} is not NUL-terminated`);
}
cursor++;
}View on GitHub (pinned to 9690622007)
Solutions
- Rebuild/re-download the package with standard rpmbuild
- Verify checksums before parsing
- If generating headers yourself, set count=0 for NULL-type entries
Example fix
// before
{ tag: 1234, type: 0, offset: 0, count: 4 } // NULL with values
// after
{ tag: 1234, type: 0, offset: 0, count: 0 } // NULL entries carry no data Defensive patterns
Strategy: try-catch
Validate before calling
// validate with standard tooling before parsing
const chk = await $`rpm -K ${path}`.quiet().nothrow();
if (chk.exitCode !== 0) throw new Error('rpm failed verification'); Type guard
null
Try / catch
try {
const rpm = await readRpmArchive(buf);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('null tag')) {
// reject non-conformant header
} else throw err;
} Prevention
- Produce packages only with standard rpmbuild
- Reject packages failing `rpm -K` before parsing
- Keep checksum verification in the ingestion pipeline
When it happens
Trigger: Header index entry with type==0 and count!==0 — non-conformant header written by broken tooling, or corrupted index bytes.
Common situations: Packages produced by non-rpm tools or custom repackers, bit corruption in the index region, fuzzed inputs.
Related errors
- Invalid RPM package: corrupt ${what} header reserved bytes
- Invalid RPM package: corrupt ${what} header magic
- Invalid RPM package: tag ${tag} points outside header data
- Invalid RPM package: string tag ${tag} has an invalid count
- Invalid RPM package: string tag ${tag} exceeds header data
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ccf47a089c6e2191.
Report an issue: GitHub.