{"record":{"id":"123114da6e001d28","repo":"can1357/oh-my-pi","slug":"rar-member-record-path-crc32-mismatch","errorCode":null,"errorMessage":"RAR member '${record.path}' CRC32 mismatch","messagePattern":"RAR member '(.+?)' CRC32 mismatch","errorType":"validation","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rar.ts","lineNumber":137,"sourceCode":"\t\t\t\toutput = rar5Decoder.decode(\n\t\t\t\t\tpacked,\n\t\t\t\t\trecord.unpackedSize,\n\t\t\t\t\trecord.dictionarySize,\n\t\t\t\t\trecord.solid,\n\t\t\t\t\trecord.version,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput = rar4Decoder.decode(\n\t\t\t\t\tpacked,\n\t\t\t\t\trecord.unpackedSize,\n\t\t\t\t\trecord.dictionarySize,\n\t\t\t\t\trecord.solid,\n\t\t\t\t\trecord.version,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (output.byteLength !== record.unpackedSize) corrupt(`member '${record.path}' size mismatch`);\n\t\t\tif (record.crc !== undefined && crc32(output) !== record.crc) {\n\t\t\t\tthrow new ArchiveError(`RAR member '${record.path}' CRC32 mismatch`);\n\t\t\t}\n\t\t\tthis.#cache.set(current, output.slice());\n\t\t}\n\t}\n}\n\n/** Probe the RAR 1.5-4.x or RAR5 signature. */\nexport function sniffRar(bytes: Uint8Array): boolean {\n\treturn findMarker(bytes) !== undefined;\n}\n\n/** Index a RAR4 or RAR5 archive and defer member decompression until extraction. */\nexport const readRar: FormatReader = async (source, options) => {\n\tif (!Number.isSafeInteger(source.size) || source.size < 0) {\n\t\tthrow new ArchiveError(\"Archive is too large to read safely\");\n\t}\n\tconst indexed = await indexRarMetadata(source, options);\n\tconst bytes = sparseBytes(source.size, indexed.segments);","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rar.ts#L119-L155","documentation":"Each RAR member stores a CRC32 of its uncompressed content. After decoding, #decode recomputes CRC32 over the output and throws when it differs from the header value — proof that the decompressed bytes do not match what the archiver originally stored.","triggerScenarios":"Decoding a member whose compressed data is damaged, whose decoder produced wrong bytes (e.g. unsupported filter silently mis-handled), or whose header CRC was altered.","commonSituations":"Failed downloads, bad sectors, interrupted transfers; multi-volume archives with a missing/mismatched part; archives transferred in text mode.","solutions":["Run `unrar t` to identify which members are bad and re-download/re-copy the archive","Recover what you can: extract other members; use `unrar kb` (keep broken) only if the data is non-critical","Check disk health (S.M.A.R.T.) if the archive is stored locally and repeatedly fails"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const bytes = await reader.read(memberPath);\n} catch (err) {\n  if (err instanceof ArchiveError && /CRC32 mismatch/.test(err.message)) {\n    // data is corrupt: stop, don't persist these bytes; attempt re-download or unrar recovery\n  }\n  throw err;\n}","preventionTips":["Never persist or use bytes after a CRC error — the library already validated them for you","Verify whole-archive integrity (`unrar t`) before bulk extraction","Use checksums/magnets with verified hashes for downloads","Keep multi-volume sets together and complete"],"tags":["rar","archive","crc","integrity","corruption"],"backgroundTag":"archive-crc-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}