can1357/oh-my-pi · error · ArchiveError
Invalid XZ output limit
Error message
Invalid XZ output limit
What it means
Thrown when the maxOutput argument passed to xzDecompress is not a valid non-negative safe integer. The limit is validated up front before any decoding work happens, so this is a caller-side input bug, not a data problem.
Source
Thrown at packages/utils/src/ar/codecs/xz.ts:494
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> {
if (!Number.isSafeInteger(maxOutput) || maxOutput < 0) throw new ArchiveError("Invalid XZ output limit");
try {
const streams = discoverStreams(bytes);
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;View on GitHub (pinned to 9690622007)
Solutions
- Pass a non-negative safe integer, e.g. 64 * 1024 * 1024
- Sanitize the value first: maxOutput = Math.floor(Number(x)); check Number.isSafeInteger
- Fix the config/flag parsing that produced the bad value
Example fix
// before await xzDecompress(bytes, Number(opts.maxMb) * 1024); // NaN if opts.maxMb undefined // after const limit = Math.max(0, Math.floor(Number(opts.maxMb ?? 64) * 1024 * 1024)); await xzDecompress(bytes, limit);
Defensive patterns
Strategy: validation
Validate before calling
function validLimit(n: unknown): n is number {
return typeof n === 'number' && Number.isSafeInteger(n) && n >= 0;
}
if (!validLimit(maxOutput)) throw new TypeError(`bad maxOutput: ${maxOutput}`); Type guard
function isSizeLimit(v: unknown): v is number {
return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
} Try / catch
try {
const out = await xzDecompress(bytes, limit);
} catch (err) {
if (err instanceof ArchiveError && err.message === 'Invalid XZ output limit') {
// caller bug, not data bug: fix the limit value upstream
} else throw err;
} Prevention
- Centralize limit parsing into one validated helper
- Coerce config values with Math.floor(Number(x)) and validate
- Never pass NaN/-1/Infinity as a size limit
When it happens
Trigger: Calling xzDecompress(bytes, maxOutput) with NaN, a negative number, a float, a non-integer, or a value beyond Number.MAX_SAFE_INTEGER.
Common situations: maxOutput read from misparsed config/CLI args (e.g. parseInt returning NaN); unit confusion (MiB vs bytes producing fractional values); unbounded defaults like -1 or Infinity.
Related errors
- Expected --${name} to be a positive integer, got ${value}
- Cache flags require --cache
- --alias requires --profile <name> or OMP_PROFILE
- goal token_budget must be a positive integer when provided
- objective is required when op=create
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/bd6b23bae6acb408.
Report an issue: GitHub.