{"record":{"id":"ea705961a6851bc4","repo":"can1357/oh-my-pi","slug":"unsupported-rar5-recovery-record","errorCode":null,"errorMessage":"Unsupported RAR5 recovery record","messagePattern":"Unsupported RAR5 recovery record","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rar.ts","lineNumber":336,"sourceCode":"\t\tconst headerStart = sizeCursor.offset;\n\t\tconst headerEnd = checkedEnd(headerStart, headerSize, bytes.byteLength, \"RAR5 header\");\n\t\tif (crc32(bytes.subarray(sizeAt, headerEnd)) !== expectedHeaderCrc) corrupt(\"RAR5 header CRC32 mismatch\");\n\t\tconst cursor = { offset: headerStart };\n\t\tconst type = readVint(bytes, cursor, headerEnd, \"header type\");\n\t\tconst flags = readVint(bytes, cursor, headerEnd, \"header flags\");\n\t\tconst extraSize = (flags & 1) !== 0 ? readVint(bytes, cursor, headerEnd, \"extra area size\") : 0;\n\t\tconst dataSize = (flags & 2) !== 0 ? readVint(bytes, cursor, headerEnd, \"data size\") : 0;\n\t\tif ((flags & 0x18) !== 0) throw new ArchiveError(\"Unsupported multi-volume RAR5 archive\");\n\t\tconst dataStart = headerEnd;\n\t\tconst dataEnd = checkedEnd(dataStart, dataSize, bytes.byteLength, \"RAR5 data area\");\n\t\tif (extraSize > headerEnd - cursor.offset) corrupt(\"invalid RAR5 extra area size\");\n\t\tconst extraStart = headerEnd - extraSize;\n\n\t\tif (type === 4) throw new ArchiveError(\"Encrypted RAR5 headers are not supported\");\n\t\tif (type === 1) {\n\t\t\tconst archiveFlags = readVint(bytes, cursor, extraStart, \"archive flags\");\n\t\t\tif ((archiveFlags & 1) !== 0) throw new ArchiveError(\"Unsupported multi-volume RAR5 archive\");\n\t\t\tif ((archiveFlags & 8) !== 0) throw new ArchiveError(\"Unsupported RAR5 recovery record\");\n\t\t\tif ((archiveFlags & 2) !== 0) readVint(bytes, cursor, extraStart, \"volume number\");\n\t\t\tsawMain = true;\n\t\t} else if (type === 2 || type === 3) {\n\t\t\tconst fileFlags = readVint(bytes, cursor, extraStart, \"file flags\");\n\t\t\tconst unpackedSize = readVint(bytes, cursor, extraStart, \"unpacked size\");\n\t\t\tif ((fileFlags & 8) !== 0) throw new ArchiveError(\"RAR5 member with unknown unpacked size is not supported\");\n\t\t\tconst attributes = readVint(bytes, cursor, extraStart, \"file attributes\");\n\t\t\tlet mtimeMs: number | undefined;\n\t\t\tif ((fileFlags & 2) !== 0) {\n\t\t\t\tneed(cursor.offset, 4, extraStart, \"RAR5 modification time\");\n\t\t\t\tmtimeMs = readUInt32LE(bytes, cursor.offset) * 1000;\n\t\t\t\tcursor.offset += 4;\n\t\t\t}\n\t\t\tlet dataCrc: number | undefined;\n\t\t\tif ((fileFlags & 4) !== 0) {\n\t\t\t\tneed(cursor.offset, 4, extraStart, \"RAR5 data CRC32\");\n\t\t\t\tdataCrc = readUInt32LE(bytes, cursor.offset);\n\t\t\t\tcursor.offset += 4;","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rar.ts#L318-L354","documentation":"The RAR5 main archive header's archive flags bit 8 (RECOVERY) means the archive ends with a recovery record (RR) used to repair damaged archives. The library does not implement recovery-record parsing, so such archives are rejected.","triggerScenarios":"Reading a RAR5 archive created with the recovery record option (WinRAR 'Add recovery record', `rar -rr`, or `rar rr` applied afterwards).","commonSituations":"Archives intended for flaky transfer media (email, Usenet, optical discs); downloaded releases that ship .rev recovery data; backup policies mandating RR.","solutions":["Re-create the archive without the recovery record option","Strip the recovery record with `rar rr` tooling or re-save with WinRAR/unrar","Parse an RR-free copy; the actual file data is unaffected"],"exampleFix":"// before\nrar a -rr backup.rar files/   // creates RR the parser rejects\n// after\nrar a backup.rar files/       // no recovery record","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const records = readRar(bytes);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('recovery record')) {\n    logger.warn('RAR has recovery record; parsing not supported');\n  } else throw err;\n}","preventionTips":["Create archives without -rr / 'Add recovery record' for programmatic use","Note that RR only helps repair; it is not needed to read intact archives"],"tags":["rar5","recovery-record","unsupported-feature","archive"],"backgroundTag":"unsupported-archive-feature","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}