{"record":{"id":"80691ec57a89d760","repo":"can1357/oh-my-pi","slug":"invalid-xz-stream-error-instanceof-error-erro","errorCode":null,"errorMessage":"Invalid XZ stream: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Invalid XZ stream: (.+?)","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/xz.ts","lineNumber":520,"sourceCode":"\t\t\t\t\tthrow new ArchiveError(\"XZ output exceeds its size limit\");\n\t\t\t}\n\t\tconst output = new Uint8Array(totalSize);\n\t\tlet outputPosition = 0;\n\t\tfor (const stream of streams) {\n\t\t\tlet blockPosition = stream.start + 12;\n\t\t\tfor (const record of stream.records) {\n\t\t\t\tconst block = await decodeBlock(bytes, blockPosition, record, stream.checkId);\n\t\t\t\toutput.set(block, outputPosition);\n\t\t\t\toutputPosition += block.byteLength;\n\t\t\t\tblockPosition += Math.ceil(record.unpaddedSize / 4) * 4;\n\t\t\t}\n\t\t\tif (blockPosition !== stream.indexStart)\n\t\t\t\tthrow new ArchiveError(\"Invalid XZ stream: blocks do not align with index\");\n\t\t}\n\t\treturn output;\n\t} catch (error) {\n\t\tif (error instanceof ArchiveError) throw error;\n\t\tthrow new ArchiveError(`Invalid XZ stream: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n}\n","sourceCodeStart":502,"sourceCodeEnd":523,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/xz.ts#L502-L523","documentation":"This is the generic catch-all in xzDecompress: any non-ArchiveError thrown during stream discovery or block decoding (range checks, filter errors, check mismatches, internal errors) is re-wrapped as 'Invalid XZ stream: <original message>'. The inner message identifies the actual root cause.","triggerScenarios":"Any malformed XZ input whose failure surfaces as a non-ArchiveError lower in the decode path — out-of-range offsets, unknown filter IDs, failed integrity checks, Bun zstd/native decompressor errors, allocation failures.","commonSituations":"Feeding a non-XZ file (e.g. gzip or plain text) to xzDecompress; truncated archives; unsupported filter chains in exotic .xz files; wrong file passed due to path mix-ups.","solutions":["Read the inner message after 'Invalid XZ stream:' to identify the root cause","Confirm the input actually starts with the XZ magic (isXz(bytes)) before decompressing","Test with xz -t / xz -d to characterize the file","Re-acquire the archive if it is truncated or corrupt"],"exampleFix":"// before\nawait xzDecompress(userFile, limit); // throws: Invalid XZ stream: ...\n// after\nimport { isXz } from '@oh-my-pi/pi-utils/ar/codecs/xz';\nif (!isXz(bytes)) throw new Error('not an XZ file');\nawait xzDecompress(bytes, limit);","handlingStrategy":"try-catch","validationCode":"import { isXz } from '@oh-my-pi/pi-utils/ar/codecs/xz';\nif (!isXz(bytes)) throw new Error(`not XZ: magic=${bytes.subarray(0, 6)}`);\nif (!Number.isSafeInteger(limit) || limit < 0) throw new TypeError('bad limit');","typeGuard":null,"tryCatchPattern":"try {\n  return await xzDecompress(bytes, limit);\n} catch (err) {\n  if (err instanceof ArchiveError && err.message.startsWith('Invalid XZ stream:')) {\n    logger.warn('xz decompress failed', { cause: err.message });\n    return null; // or re-fetch / fall back to another codec\n  }\n  throw err;\n}","preventionTips":["Check isXz() before decompressing any file whose format is inferred from extension","Log the full message — the suffix names the real root cause","Route files by magic bytes, not by extension alone"],"tags":["xz","archive","corruption","wrapper"],"backgroundTag":"xz-stream-corrupt","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}