{"record":{"id":"47091714a4c510ea","repo":"can1357/oh-my-pi","slug":"failed-to-extract-rar-member-memberpath","errorCode":null,"errorMessage":"Failed to extract RAR member '${memberPath}'","messagePattern":"Failed to extract RAR member '(.+?)'","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/rar.ts","lineNumber":73,"sourceCode":"\n\tconstructor(source: ByteSource, records: RarRecord[], options: FormatReadOptions) {\n\t\tthis.#source = source;\n\t\tthis.#records = records;\n\t\tthis.#limits = options.limits;\n\t}\n\n\tmember(index: number): MemberSource {\n\t\treturn new RarMemberSource(this, index);\n\t}\n\n\tasync read(index: number, size: number, memberPath: string): Promise<Uint8Array> {\n\t\tconst pending = this.#queue.then(async () => {\n\t\t\tif (!this.#cache.has(index)) await this.#decode(index);\n\t\t});\n\t\tthis.#queue = pending.catch(() => undefined);\n\t\tawait pending;\n\t\tconst bytes = this.#cache.get(index);\n\t\tif (!bytes) throw new ArchiveError(`Failed to extract RAR member '${memberPath}'`);\n\t\tif (bytes.byteLength !== size) {\n\t\t\tthrow new ArchiveError(`RAR member '${memberPath}' size mismatch (${bytes.byteLength} != ${size})`);\n\t\t}\n\t\treturn bytes.slice();\n\t}\n\n\tasync #decode(index: number): Promise<void> {\n\t\tconst target = this.#records[index];\n\t\tif (!target) throw new ArchiveError(\"Invalid RAR member index\");\n\t\tlet start = index;\n\t\tif (target.solid) {\n\t\t\twhile (start > 0 && this.#records[start]!.solid && this.#records[start - 1]!.format === target.format) start--;\n\t\t}\n\t\tconst rar4Decoder = new Rar4Decoder();\n\t\tconst rar5Decoder = new Rar5Decoder();\n\t\tfor (let current = start; current <= index; current++) {\n\t\t\tconst record = this.#records[current]!;\n\t\t\tif (record.isDirectory) continue;","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/rar.ts#L55-L91","documentation":"Thrown by the RarArchiveReader.read() when, after queuing and awaiting #decode for the requested member, the decoded bytes are absent from the cache. Since #decode always populates the cache on success, this indicates the decode failed silently or produced no entry for the index.","triggerScenarios":"Calling reader.read(memberPath) after a previous decode error was swallowed (the queue chain uses pending.catch(() => undefined)), then the cache lookup for the index returns undefined.","commonSituations":"Sequential reads over solid archives where an earlier member failed to decode and the error was absorbed; reading the same member twice after an internal failure.","solutions":["Inspect the original decode failure: re-open the archive and read the member in a fresh reader so the real error surfaces","Test the archive with `unrar t` to find the failing member","Check for the companion errors (unsupported version/method, CRC mismatch) that cause #decode to fail"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Read members in listing order and fail fast on the first error so the\n// swallowed-queue path never hides the root cause:\nfor (const member of reader.list()) {\n  await reader.read(member.path); // surfaces real decode errors immediately\n}","typeGuard":null,"tryCatchPattern":"try {\n  const bytes = await reader.read(memberPath);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.startsWith('Failed to extract RAR member')) {\n    // re-open the archive and retry once; the retry surfaces the real decode error\n  }\n  throw err;\n}","preventionTips":["Open a fresh reader after any failed read instead of reusing one whose internal queue absorbed an error","Read solid-archive members in order so decode failures surface at the failing member","Verify archives with `unrar t` before extraction"],"tags":["rar","archive","extraction-failure","cache"],"backgroundTag":"archive-member-extraction-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}