can1357/oh-my-pi · error · ArchiveError
Invalid XZ stream: ${error instanceof Error ? error.message
Error message
Invalid XZ stream: ${error instanceof Error ? error.message : String(error)} What it means
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.
Source
Thrown at packages/utils/src/ar/codecs/xz.ts:520
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
- 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
Example fix
// before
await xzDecompress(userFile, limit); // throws: Invalid XZ stream: ...
// after
import { isXz } from '@oh-my-pi/pi-utils/ar/codecs/xz';
if (!isXz(bytes)) throw new Error('not an XZ file');
await xzDecompress(bytes, limit); Defensive patterns
Strategy: try-catch
Validate before calling
import { isXz } from '@oh-my-pi/pi-utils/ar/codecs/xz';
if (!isXz(bytes)) throw new Error(`not XZ: magic=${bytes.subarray(0, 6)}`);
if (!Number.isSafeInteger(limit) || limit < 0) throw new TypeError('bad limit'); Try / catch
try {
return await xzDecompress(bytes, limit);
} catch (err) {
if (err instanceof ArchiveError && err.message.startsWith('Invalid XZ stream:')) {
logger.warn('xz decompress failed', { cause: err.message });
return null; // or re-fetch / fall back to another codec
}
throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid XZ stream: block size does not match its index recor
- Invalid XZ stream: blocks do not align with index
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
- ARJ member '${memberPath}' has inconsistent stored size
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/80691ec57a89d760.
Report an issue: GitHub.