{"record":{"id":"32b12361d4df7a2f","repo":"can1357/oh-my-pi","slug":"invalid-cab-archive-mszip-decompression-failed-e","errorCode":null,"errorMessage":"Invalid CAB archive: MSZIP decompression failed${error instanceof Error ? `: ${error.message}` : \"\"}","messagePattern":"Invalid CAB archive: MSZIP decompression failed(.+?)` : \"\"\\}","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/cab.ts","lineNumber":197,"sourceCode":"\t\t\tconst uncompressed = readUInt16LE(bytes, position + 6);\n\t\t\tconst payloadStart = position + DATA_BLOCK_SIZE + this.#dataReserveSize;\n\t\t\tconst payloadEnd = payloadStart + compressed;\n\t\t\tconst payload = bytes.subarray(payloadStart, payloadEnd);\n\t\t\tlet decoded: Uint8Array;\n\t\t\tif (description.method === 0) {\n\t\t\t\tif (compressed !== uncompressed) {\n\t\t\t\t\tthrow new ArchiveError(\"Invalid CAB archive: uncompressed CFDATA sizes do not match\");\n\t\t\t\t}\n\t\t\t\tdecoded = payload;\n\t\t\t} else if (description.method === 1) {\n\t\t\t\tif (payload.byteLength < 2 || payload[0] !== 0x43 || payload[1] !== 0x4b) {\n\t\t\t\t\tthrow new ArchiveError(\"Invalid CAB archive: MSZIP block is missing its CK signature\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst dictionary = output.subarray(Math.max(0, outputPosition - MAX_DATA_OUTPUT), outputPosition);\n\t\t\t\t\tdecoded = new Uint8Array(\n\t\t\t\t\t\tzlib.inflateRawSync(payload.subarray(2), { dictionary, maxOutputLength: uncompressed }),\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new ArchiveError(\n\t\t\t\t\t\t`Invalid CAB archive: MSZIP decompression failed${error instanceof Error ? `: ${error.message}` : \"\"}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdecoded = lzx!.decompressFrame(payload, uncompressed);\n\t\t\t}\n\t\t\tif (decoded.byteLength !== uncompressed) {\n\t\t\t\tthrow new ArchiveError(\n\t\t\t\t\t`Invalid CAB archive: CFDATA block ${block} produced ${decoded.byteLength} bytes, expected ${uncompressed}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\toutput.set(decoded, outputPosition);\n\t\t\toutputPosition += decoded.byteLength;\n\t\t\tposition = payloadEnd;\n\t\t}\n\t\treturn output;","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/cab.ts#L179-L215","documentation":"Thrown by CabFolder.#decode when node:zlib's inflateRawSync rejects the deflate stream inside an MSZIP block (after the 'CK' signature). The original zlib error message is appended so you can see the underlying zlib failure (e.g. 'invalid distance too far back', unexpected end of file). MSZIP inflate also receives the previous 32KB of folder output as the dictionary window, so mid-folder failures can indicate missing or wrong preceding data.","triggerScenarios":"readCab() indexed a method-1 folder and zlib.inflateRawSync(payload.subarray(2), {dictionary, maxOutputLength}) threw — corrupt deflate stream, wrong dictionary window due to an earlier failed block, or truncated payload.","commonSituations":"Partially corrupted archives; extracting method-1 cabinets where an earlier block was silently damaged so the 32KB MSZIP history window is wrong; files from unreliable sources.","solutions":["Read the appended zlib message to identify the inflate failure mode","Re-download/verify the archive with `cabextract -t`; re-obtain if corrupt","If failure happens deep in a multi-block folder, suspect corruption in an earlier block (it seeds the MSZIP dictionary)","Regenerate the cabinet with makecab/7-Zip if you control production; otherwise report a bug if cabextract succeeds"],"exampleFix":"// before\ntry { await extractCab(path, dest); } catch { console.log('failed'); }\n// after\ntry { await extractCab(path, dest); }\ncatch (err) {\n  if (err instanceof ArchiveError && err.message.includes('MSZIP decompression failed'))\n    console.error(`archive corrupt at MSZIP block: ${err.message}`);\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"const t = Bun.$`cabextract -t ${path}`.quiet().nothrow();\nif ((await t).exitCode !== 0) throw new Error(`corrupt cabinet: ${path}`);","typeGuard":null,"tryCatchPattern":"try {\n  await readCab(source, opts);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.includes('MSZIP decompression failed')) {\n    logger.error('MSZIP inflate failed', { path: archivePath, detail: err.message });\n    throw new Error(`Archive corrupt at an MSZIP block: ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Log the appended zlib detail — it pinpoints the corruption type","Re-download rather than retry: deflate corruption is not transient","For multi-block folders, remember an early bad block poisons later MSZIP dictionary windows"],"tags":["archive","cab","mszip","zlib","decompression"],"backgroundTag":"decompression-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}