{"record":{"id":"f531af28846b0188","repo":"can1357/oh-my-pi","slug":"invalid-rpm-package-bad-lead-magic","errorCode":null,"errorMessage":"Invalid RPM package: bad lead magic","messagePattern":"Invalid RPM package: bad lead magic","errorType":"validation","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rpm.ts","lineNumber":247,"sourceCode":"\t\t\treturn xzDecompress(payload, maxOutput);\n\t\tcase \"zstd\":\n\t\tcase \"zstdio\":\n\t\t\treturn zstdDecompress(payload, maxOutput);\n\t\tcase \"lzma\":\n\t\t\tif (!sniffLzmaAlone(payload)) throw new ArchiveError(`RPM package '${identity}' has a malformed LZMA payload`);\n\t\t\treturn lzmaAloneDecompress(payload, maxOutput);\n\t\tcase \"none\":\n\t\t\tif (!sniffCpio(payload))\n\t\t\t\tthrow new ArchiveError(`RPM package '${identity}' has an invalid uncompressed CPIO payload`);\n\t\t\treturn payload;\n\t\tdefault:\n\t\t\tthrow new ArchiveError(`RPM package '${identity}' uses unsupported payload compressor '${method}'`);\n\t}\n}\n\nasync function readRpmArchive(source: ByteSource, options: FormatReadOptions): Promise<ArchiveIndexEntry[]> {\n\tconst initial = await readExact(source, 0, RPM_LEAD_SIZE + RPM_HEADER_INTRO_SIZE, \"lead and signature header\");\n\tif (!sniffRpm(initial)) throw new ArchiveError(\"Invalid RPM package: bad lead magic\");\n\tconst major = initial[4]!;\n\tconst packageType = (initial[6]! << 8) | initial[7]!;\n\tif (major < 3 || packageType > 1) throw new ArchiveError(\"Unsupported RPM package lead version or type\");\n\tconst signatureType = (initial[78]! << 8) | initial[79]!;\n\tif (signatureType !== RPM_SIGNATURE_TYPE_HEADER) {\n\t\tthrow new ArchiveError(`Unsupported RPM signature type ${signatureType}; only header signatures are supported`);\n\t}\n\tconst leadNameEnd = initial.subarray(10, 76).indexOf(0);\n\tconst leadNameBytes = initial.subarray(10, leadNameEnd < 0 ? 76 : 10 + leadNameEnd);\n\tlet leadName = \"unknown package\";\n\ttry {\n\t\tconst decoded = new TextDecoder(\"utf-8\", { fatal: true }).decode(leadNameBytes);\n\t\tif (decoded) leadName = decoded;\n\t} catch {}\n\n\tconst signatureIntro = parseHeaderIntro(initial.subarray(RPM_LEAD_SIZE), options, \"signature\");\n\tconst signatureEnd = RPM_LEAD_SIZE + signatureIntro.totalSize;\n\tconst mainHeaderOffset = align(signatureEnd, 8);","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rpm.ts#L229-L265","documentation":"readRpmArchive reads the first 96-byte RPM lead plus header intro and checks the lead magic (0xEDABEEDB via sniffRpm). If the bytes do not match, the file is not an RPM package at all, so the reader fails fast before any parsing.","triggerScenarios":"Calling the RPM reader (readRpm/metadata) on a file whose first four bytes are not the RPM lead magic — e.g. a .deb, a tarball, an HTML error page saved as .rpm, or an empty/zero-byte file path.","commonSituations":"Pointing the reader at the wrong file (deb vs rpm), downloading a mirror's 404 page instead of the package, passing a source RPM stream that was already partially consumed, or a URL redirect to a login page.","solutions":["Verify the file path/URL actually points to an RPM; check the first bytes with `file <path>` — it should report 'RPM v3/v4'.","Inspect the start of the response: if it's HTML, fix the download URL (mirror 404/redirect) and re-download.","Ensure you are using the RPM reader and not passing a .deb/.tar.gz to it; route each file to the right format reader.","Checksum-verify the download to confirm you got the real package."],"exampleFix":"// before\nconst entries = await readRpm(maybeRpmPath);\n// after: sniff before parsing\nconst head = new Uint8Array(await Bun.file(path).slice(0, 4).arrayBuffer());\nif (!(head[0] === 0xed && head[1] === 0xab && head[2] === 0xee && head[3] === 0xdb)) throw new Error('not an RPM file');","handlingStrategy":"validation","validationCode":"export async function isRpmFile(path: string): Promise<boolean> {\n  const b = new Uint8Array(await Bun.file(path).slice(0, 4).arrayBuffer());\n  return b[0] === 0xed && b[1] === 0xab && b[2] === 0xee && b[3] === 0xdb;\n}\n// call before readRpm","typeGuard":"function isRpmLead(head: Uint8Array): boolean {\n  return head.length >= 4 && head[0] === 0xed && head[1] === 0xab && head[2] === 0xee && head[3] === 0xdb;\n}","tryCatchPattern":"try {\n  return await readRpm(path);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('bad lead magic')) {\n    throw new Error(`${path} is not an RPM file (bad magic); check path/download`);\n  }\n  throw err;\n}","preventionTips":["Sniff magic bytes (or run `file`) before dispatching to a format reader.","Check downloaded file sizes/HTML bodies to catch mirror 404 pages saved as .rpm.","Validate content-type and checksums on downloads."],"tags":["rpm","file-format","wrong-file","magic-bytes"],"backgroundTag":"invalid-archive-magic","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}