can1357/oh-my-pi · error · ArchiveError
Invalid XZ stream: decoded block size mismatch
Error message
Invalid XZ stream: decoded block size mismatch
What it means
After LZMA2 decompression the output length must equal the uncompressed size recorded in the stream index. A mismatch means the compressed payload, LZMA2 properties, or index record are inconsistent — the decoder refuses to return wrong-sized data.
Source
Thrown at packages/utils/src/ar/codecs/xz.ts:475
if (declaredCompressed !== undefined && declaredCompressed !== compressedSize)
throw new ArchiveError("Invalid XZ stream: block compressed size mismatch");
if (declaredUncompressed !== undefined && declaredUncompressed !== record.uncompressedSize)
throw new ArchiveError("Invalid XZ stream: block uncompressed size mismatch");
const compressedStart = offset + headerSize;
const compressedEnd = compressedStart + compressedSize;
const paddingSize = (4 - ((headerSize + compressedSize) & 3)) & 3;
const checkStart = compressedEnd + paddingSize;
if (checkStart + integritySize > bytes.byteLength) throw new ArchiveError("Invalid XZ stream: truncated block data");
const last = filters[filters.length - 1]!;
if (last.id !== 0x21 || last.properties.byteLength !== 1)
throw new ArchiveError(`Unsupported XZ terminal filter ID 0x${last.id.toString(16)} (LZMA2 required)`);
let output = await lzma2Decompress(
last.properties[0]!,
bytes.subarray(compressedStart, compressedEnd),
record.uncompressedSize,
);
if (output.byteLength !== record.uncompressedSize)
throw new ArchiveError("Invalid XZ stream: decoded block size mismatch");
output = output.slice();
for (let index = filters.length - 2; index >= 0; index--) applyFilter(output, filters[index]!);
for (let index = compressedEnd; index < checkStart; index++)
if (bytes[index] !== 0) throw new ArchiveError("Invalid XZ stream: non-zero block padding");
verifyCheck(checkId, output, bytes.subarray(checkStart, checkStart + integritySize));
const paddedEnd = offset + Math.ceil(record.unpaddedSize / 4) * 4;
if (checkStart + integritySize !== paddedEnd)
throw new ArchiveError("Invalid XZ stream: block size does not match its index record");
return output;
}
/** Whether bytes begin with the XZ stream-header magic. */
export function isXz(bytes: Uint8Array): boolean {
return bytes.byteLength >= XZ_MAGIC.byteLength && equalBytes(bytes.subarray(0, XZ_MAGIC.byteLength), XZ_MAGIC);
}
/** Decompress all concatenated streams in an XZ container within `maxOutput`. */
export async function xzDecompress(bytes: Uint8Array, maxOutput: number): Promise<Uint8Array> {View on GitHub (pinned to 9690622007)
Solutions
- Validate with `xz -t` and re-download the archive from a trusted source.
- Re-compress with the standard xz tool if the producer was custom or non-standard.
- Check that the compressed byte range was not altered (no manual slicing/splicing of the stream).
- Report the archive as corrupt rather than attempting partial recovery.
Defensive patterns
Strategy: try-catch
Validate before calling
const ok = await $`xz -t ${path}`.quiet().nothrow();
if (ok.exitCode !== 0) throw new Error(`XZ integrity check failed: ${path}`); Try / catch
try {
return await xzDecompress(bytes, maxOutput);
} catch (err) {
if (err instanceof ArchiveError && /size mismatch/i.test(err.message)) {
throw new Error('Decompressed data does not match the index — archive is corrupt');
}
throw err;
} Prevention
- Verify checksums before decompression to catch bit rot early.
- Never splice or rewrite XZ stream indexes.
- Re-encode suspicious archives with the standard xz tool.
- Monitor storage: recurring size mismatches indicate failing media.
When it happens
Trigger: xzDecompress decompresses a block whose lzma2Decompress output byteLength differs from record.uncompressedSize — e.g. the index claims a different size than the payload actually produces, or LZMA2 properties (dict size byte) are wrong for the payload.
Common situations: Bit-corrupted compressed data, archives whose index was rewritten or spliced, or files produced by encoders that misreport uncompressed sizes.
Related errors
- Invalid XZ stream: non-canonical variable-length integer
- Unsupported XZ block flags
- Invalid XZ stream: truncated filter properties
- Invalid XZ stream: non-zero block header padding
- Invalid XZ stream: compressed block size is invalid
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8a4a16e480199805.
Report an issue: GitHub.