{"record":{"id":"287ac7efdd06241b","repo":"can1357/oh-my-pi","slug":"arj-member-memberpath-extracted-to-an-unexpec","errorCode":null,"errorMessage":"ARJ member '${memberPath}' extracted to an unexpected size","messagePattern":"ARJ member '(.+?)' extracted to an unexpected size","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/arj.ts","lineNumber":201,"sourceCode":"\t\t\tcase 2:\n\t\t\tcase 3:\n\t\t\t\toutput = decompressLhStatic(packed, size, 26_624, 5, 17, `ARJ method ${this.#method}`);\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\toutput = decompressArjMethod4(packed, size);\n\t\t\t\tbreak;\n\t\t\tcase 8:\n\t\t\tcase 9:\n\t\t\t\tif (size !== 0 || packed.byteLength !== 0) {\n\t\t\t\t\tthrow new ArchiveError(`ARJ member '${memberPath}' has invalid no-data method sizes`);\n\t\t\t\t}\n\t\t\t\toutput = new Uint8Array(0);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new ArchiveError(`ARJ member '${memberPath}' uses unsupported compression method ${this.#method}`);\n\t\t}\n\t\tif (output.byteLength !== size)\n\t\t\tthrow new ArchiveError(`ARJ member '${memberPath}' extracted to an unexpected size`);\n\t\tif (this.#method !== 8 && crc32(output) !== this.#crc) {\n\t\t\tthrow new ArchiveError(`ARJ member '${memberPath}' failed CRC32 verification`);\n\t\t}\n\t\treturn output;\n\t}\n}\n\nfunction normalizeHostPath(rawPath: string, hostOs: number): string {\n\tlet path = rawPath.replaceAll(\"\\\\\", \"/\");\n\tif (hostOs === 1) path = path.replaceAll(\">\", \"/\");\n\telse if (hostOs === 4) path = path.replaceAll(\":\", \"/\");\n\treturn path;\n}\n\n/** Probe whether bytes begin with a CRC-framed ARJ main header. */\nexport function sniffArj(bytes: Uint8Array): boolean {\n\tif (bytes.byteLength < 34 || bytes[0] !== ARJ_SIGNATURE_0 || bytes[1] !== ARJ_SIGNATURE_1) return false;\n\tconst size = u16(bytes, 2);","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/arj.ts#L183-L219","documentation":"This ArchiveError is thrown as a post-decompression invariant: the decompressor's output length does not equal the size declared in the member's local header. For stored members this is caught earlier, so this usually indicates a decoder produced fewer/more bytes than requested for methods 1–4, or the header's size field is wrong.","triggerScenarios":"Calling member.read(size, memberPath) where decompressLhStatic (methods 1–3) or decompressArjMethod4 (method 4) returns an output whose byteLength differs from size — typically because the packed stream is corrupt or the declared uncompressed size is wrong.","commonSituations":"Bit-rot or partial downloads corrupting compressed streams, archives written by buggy tools with wrong size fields, mixed-method archives assembled incorrectly.","solutions":["Test the archive with the official arj tool (arj t) to confirm corruption.","Re-download or restore the archive from a good copy.","Re-create the archive with a compliant tool.","If the header size is genuinely wrong, patch the extraction to trust the decompressed length only when it matches, and skip members that fail."],"exampleFix":"// before\nconst data = await member.read(member.size, member.path);\n// after\ntry {\n  const data = await member.read(member.size, member.path);\n} catch (e) {\n  if (e instanceof ArchiveError && e.message.includes('unexpected size')) {\n    console.warn(`member ${member.path} size mismatch; archive header may be corrupt`);\n    return null;\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const data = await member.read(size, path);\n} catch (e) {\n  if (e instanceof ArchiveError && e.message.includes('unexpected size')) {\n    // archive header or compressed stream is corrupt; skip member\n  } else throw e;\n}","preventionTips":["Verify archive integrity (arj t) before extraction","Re-download archives that fail any member read","Do not trust archives with header size fields that disagree with actual decompressed lengths"],"tags":["archive","arj","corruption","size-mismatch"],"backgroundTag":"archive-member-corrupt","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}