{"record":{"id":"42e2169ab39a7c21","repo":"can1357/oh-my-pi","slug":"invalid-rpm-package-tag-tag-must-contain-one-s","errorCode":null,"errorMessage":"Invalid RPM package: tag ${tag} must contain one string","messagePattern":"Invalid RPM package: tag (.+?) must contain one string","errorType":"validation","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rpm.ts","lineNumber":128,"sourceCode":"\t\t\tthrow new ArchiveError(`Invalid RPM package: tag ${tag} uses unknown data type ${type}`);\n\t\t}\n\t\tif (offset % elementSize !== 0) throw new ArchiveError(`Invalid RPM package: tag ${tag} data is misaligned`);\n\t\tif (count * elementSize > remaining)\n\t\t\tthrow new ArchiveError(`Invalid RPM package: tag ${tag} exceeds header data`);\n\t}\n}\n\nfunction readHeaderString(\n\tbody: Uint8Array,\n\tindexSize: number,\n\tdataSize: number,\n\toffset: number,\n\tcount: number,\n\ttype: number,\n\ttag: number,\n): string {\n\tif (type !== RPM_TYPE_STRING || count !== 1) {\n\t\tthrow new ArchiveError(`Invalid RPM package: tag ${tag} must contain one string`);\n\t}\n\tconst start = indexSize + offset;\n\tconst limit = indexSize + dataSize;\n\tlet end = start;\n\twhile (end < limit && body[end] !== 0) end++;\n\tif (end === limit) throw new ArchiveError(`Invalid RPM package: tag ${tag} string is not NUL-terminated`);\n\tif (end - start > 4096) throw new ArchiveError(`Invalid RPM package: tag ${tag} string is too large`);\n\ttry {\n\t\treturn UTF8_FATAL_DECODER.decode(body.subarray(start, end));\n\t} catch {\n\t\tthrow new ArchiveError(`Invalid RPM package: tag ${tag} is not valid UTF-8`);\n\t}\n}\n\nfunction parseMainHeader(body: Uint8Array, intro: HeaderIntro): RpmMetadata {\n\tvalidateHeaderBody(body, intro, \"main\");\n\tconst indexSize = intro.indexCount * RPM_INDEX_ENTRY_SIZE;\n\tif (body.byteLength !== intro.bodySize) throw new ArchiveError(\"Invalid RPM package: truncated main header\");","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rpm.ts#L110-L146","documentation":"readHeaderString extracts a single-string value for known metadata tags (NAME, VERSION, PAYLOAD_FORMAT, PAYLOAD_COMPRESSOR, PAYLOAD_FLAGS). Those tags must be typed STRING (6) with count 1; if the main header declares them otherwise (e.g. an INT32 version, or a string array), the parser refuses to decode them as strings rather than producing garbage.","triggerScenarios":"parseMainHeader (via readRpmArchive/readRpm) finds one of tags 1000/1001/1124/1125/1126 with type != 6 or count != 1, e.g. a package whose payload compressor tag is stored as a binary blob or array.","commonSituations":"Packages built by non-rpm tooling that stores metadata tags with wrong types; corruption flipping a tag's type field; experimental/custom header layouts.","solutions":["Rebuild the package with standard rpmbuild so metadata tags are STRING type with count 1.","If the file is downloaded, re-download and verify checksum — the type field may be corrupted.","Inspect the header with `rpm -qp --qf` or `rpm2cpio | less` to see actual tag types.","Catch ArchiveError around readRpm and fall back to lead-level identity (lead name) instead of header metadata."],"exampleFix":"// before: trusting metadata presence\nconst entries = await readRpm(source, options);\n// after: degrade gracefully when header metadata is malformed\nlet entries;\ntry {\n  entries = await readRpm(source, options);\n} catch (err) {\n  if (err instanceof ArchiveError && /must contain one string/.test(err.message)) {\n    entries = await readArchiveWithoutRpmMetadata(source, options);\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let metadata;\ntry {\n  metadata = (await readRpm(source, options)).metadata;\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes(\"must contain one string\")) {\n    metadata = { name: leadNameFallback }; // degrade to lead-level identity\n  } else throw err;\n}","preventionTips":["Build packages with standard rpmbuild so metadata tags use STRING type/count 1.","Verify checksums to rule out corruption of the type/count fields.","Fall back to lead (filename) identity when header metadata is unusable."],"tags":["rpm","archive","header-validation","metadata"],"backgroundTag":"rpm-header-validation-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}