can1357/oh-my-pi · error · ArchiveError

Invalid XZ stream: blocks do not align with index

Error message

Invalid XZ stream: blocks do not align with index

What it means

After decoding each block in an XZ stream, the library walks the block positions using index-record sizes and requires the final position to land exactly on the stream's index start. If it doesn't, the block sequence and the index disagree — the stream layout is inconsistent.

Source

Thrown at packages/utils/src/ar/codecs/xz.ts:515

		let totalSize = 0;
		for (const stream of streams)
			for (const record of stream.records) {
				totalSize += record.uncompressedSize;
				if (!Number.isSafeInteger(totalSize) || totalSize > maxOutput)
					throw new ArchiveError("XZ output exceeds its size limit");
			}
		const output = new Uint8Array(totalSize);
		let outputPosition = 0;
		for (const stream of streams) {
			let blockPosition = stream.start + 12;
			for (const record of stream.records) {
				const block = await decodeBlock(bytes, blockPosition, record, stream.checkId);
				output.set(block, outputPosition);
				outputPosition += block.byteLength;
				blockPosition += Math.ceil(record.unpaddedSize / 4) * 4;
			}
			if (blockPosition !== stream.indexStart)
				throw new ArchiveError("Invalid XZ stream: blocks do not align with index");
		}
		return output;
	} catch (error) {
		if (error instanceof ArchiveError) throw error;
		throw new ArchiveError(`Invalid XZ stream: ${error instanceof Error ? error.message : String(error)}`);
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Obtain an intact copy of the archive and re-decompress
  2. Verify with xz -t to confirm the container is broken independently of this library
  3. If you construct XZ data programmatically, regenerate the index whenever blocks change
Defensive patterns

Strategy: validation

Validate before calling

import { isXz } from '@oh-my-pi/pi-utils/ar/codecs/xz';
if (!isXz(bytes)) throw new Error('not XZ');
// integrity check out of band before parsing
// e.g. run: Bun.spawnSync(['xz','-t','--file',path])

Try / catch

try {
  const out = await xzDecompress(bytes, limit);
} catch (err) {
  if (err instanceof ArchiveError && /blocks do not align with index/.test(err.message)) {
    // stream layout broken: re-acquire the archive
  } else throw err;
}

Prevention

When it happens

Trigger: Calling xzDecompress on bytes where block padding was altered, blocks were added/removed without regenerating the index, or the bytes are a spliced mix of two XZ streams.

Common situations: Archives modified or repaired by non-conformant tools; corruption in the middle of a .xz file; manually concatenated files where stream framing was broken.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/a582aac7d040f822. Report an issue: GitHub.