{"record":{"id":"850151ad1bb33a08","repo":"can1357/oh-my-pi","slug":"unsupported-xz-block-flags","errorCode":null,"errorMessage":"Unsupported XZ block flags","messagePattern":"Unsupported XZ block flags","errorType":"exception","errorClass":"ArchiveError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/ar/codecs/xz.ts","lineNumber":438,"sourceCode":"\t\tfor (let index = 0; index < 8; index++) stored |= BigInt(expected[index]!) << BigInt(index * 8);\n\t\tif (actual !== stored) throw new ArchiveError(\"Invalid XZ stream: block CRC64 mismatch\");\n\t\treturn;\n\t}\n\tconst actual = new Uint8Array(new Bun.CryptoHasher(\"sha256\").update(output).digest());\n\tif (!equalBytes(actual, expected)) throw new ArchiveError(\"Invalid XZ stream: block SHA-256 mismatch\");\n}\n\nasync function decodeBlock(bytes: Uint8Array, offset: number, record: XzRecord, checkId: number): Promise<Uint8Array> {\n\tif (offset >= bytes.byteLength || bytes[offset] === 0)\n\t\tthrow new ArchiveError(\"Invalid XZ stream: missing block header\");\n\tconst headerSize = (bytes[offset]! + 1) * 4;\n\tif (offset + headerSize > bytes.byteLength || headerSize < 8)\n\t\tthrow new ArchiveError(\"Invalid XZ stream: truncated block header\");\n\tif (crc32(bytes.subarray(offset, offset + headerSize - 4)) !== read32LE(bytes, offset + headerSize - 4))\n\t\tthrow new ArchiveError(\"Invalid XZ stream: block header CRC32 mismatch\");\n\tconst cursor: Cursor = { bytes, pos: offset + 1, limit: offset + headerSize - 4 };\n\tconst flags = bytes[cursor.pos++]!;\n\tif ((flags & 0x3c) !== 0) throw new ArchiveError(\"Unsupported XZ block flags\");\n\tconst filterCount = (flags & 3) + 1;\n\tconst declaredCompressed = (flags & 0x40) !== 0 ? readVarInt(cursor) : undefined;\n\tconst declaredUncompressed = (flags & 0x80) !== 0 ? readVarInt(cursor) : undefined;\n\tconst filters: XzFilter[] = [];\n\tfor (let index = 0; index < filterCount; index++) {\n\t\tconst id = readVarInt(cursor);\n\t\tconst propertySize = readVarInt(cursor);\n\t\tif (propertySize > cursor.limit - cursor.pos)\n\t\t\tthrow new ArchiveError(\"Invalid XZ stream: truncated filter properties\");\n\t\tfilters.push({ id, properties: bytes.slice(cursor.pos, cursor.pos + propertySize) });\n\t\tcursor.pos += propertySize;\n\t}\n\twhile (cursor.pos < cursor.limit)\n\t\tif (bytes[cursor.pos++] !== 0) throw new ArchiveError(\"Invalid XZ stream: non-zero block header padding\");\n\tconst integritySize = checkSize(checkId);\n\tconst compressedSize = record.unpaddedSize - headerSize - integritySize;\n\tif (!Number.isSafeInteger(compressedSize) || compressedSize <= 0)\n\t\tthrow new ArchiveError(\"Invalid XZ stream: compressed block size is invalid\");","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/ar/codecs/xz.ts#L420-L456","documentation":"The XZ block header's flags byte has bits 2-5 (0x3c) set, which are reserved by the XZ format and must be zero. This decoder strictly validates the format and rejects the block rather than guessing. It is thrown while parsing a block header inside xzDecompress/decodeBlock (packages/utils/src/ar/codecs/xz.ts:438).","triggerScenarios":"Calling xzDecompress (or an archive-extract API that routes to it) on bytes whose block header flags byte contains any of the reserved bits 0x3c — i.e. a corrupt, hand-edited, or non-conforming XZ file.","commonSituations":"Corrupted downloads (truncated then re-saved archives), files produced by buggy or experimental XZ encoders, bit-flipped bytes on damaged storage, or mistaking a similarly-named non-XZ file for an XZ stream.","solutions":["Re-download or restore the .xz file and verify its checksum against the published one.","Test the file with `xz -t file.xz` (or `xz -l`) to confirm it is valid; re-compress with `xz` if the source encoder was non-standard.","Ensure you are passing the full XZ stream bytes, not a slice starting mid-file, to xzDecompress.","If you need reserved-flag XZ variants, they are out of scope for this decoder; use a full-featured XZ implementation."],"exampleFix":"// before\nawait xzDecompress(partiallyDownloadedBytes, maxOutput);\n// after\nconst bytes = await Bun.file('archive.tar.xz').bytes();\nawait xzDecompress(bytes, maxOutput); // complete, checksum-verified file","handlingStrategy":"try-catch","validationCode":"import { isXz } from '@oh-my-pi/pi-utils/ar/codecs/xz';\nif (!isXz(bytes)) throw new Error('Not an XZ stream');","typeGuard":"function isXzStream(bytes: Uint8Array): boolean {\n\tconst magic = [0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00];\n\treturn bytes.byteLength >= magic.length && magic.every((b, i) => bytes[i] === b);\n}","tryCatchPattern":"import { ArchiveError } from '@oh-my-pi/pi-utils/ar';\ntry {\n\tconst out = await xzDecompress(bytes, maxOutput);\n} catch (err) {\n\tif (err instanceof ArchiveError) {\n\t\tlogger.warn('XZ archive invalid, skipping', { message: err.message });\n\t\treturn fallbackPath();\n\t}\n\tthrow err;\n}","preventionTips":["Verify file checksums before decompressing untrusted or transferred archives.","Sanity-check the XZ magic bytes before calling xzDecompress.","Never hand-edit or post-process archive bytes.","Probe with `xz -t` during ingestion pipelines for batch archives."],"tags":["archive","xz","corrupt-data","format-validation"],"backgroundTag":"xz-block-flags-invalid","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}