can1357/oh-my-pi · error · ArchiveError
Invalid XZ stream: truncated variable-length integer
Error message
Invalid XZ stream: truncated variable-length integer
What it means
XZ variable-length integers (multibyte, up to 9 bytes) encode sizes in the block header and index. readVarInt throws when the cursor reaches its limit before encountering a byte with the continuation bit clear — the integer is cut off by the end of the valid region.
Source
Thrown at packages/utils/src/ar/codecs/xz.ts:45
bytes[offset + 3] = value & 0xff;
}
function equalBytes(left: Uint8Array, right: Uint8Array): boolean {
if (left.byteLength !== right.byteLength) return false;
for (let index = 0; index < left.byteLength; index++) if (left[index] !== right[index]) return false;
return true;
}
interface Cursor {
bytes: Uint8Array;
pos: number;
limit: number;
}
function readVarInt(cursor: Cursor): number {
let value = 0;
for (let index = 0; index < 9; index++) {
if (cursor.pos >= cursor.limit) throw new ArchiveError("Invalid XZ stream: truncated variable-length integer");
const byte = cursor.bytes[cursor.pos++]!;
if (index > 0 && byte === 0) throw new ArchiveError("Invalid XZ stream: non-canonical variable-length integer");
value += (byte & 0x7f) * 2 ** (index * 7);
if (!Number.isSafeInteger(value)) throw new ArchiveError("XZ stream uses sizes too large to read safely");
if ((byte & 0x80) === 0) return value;
}
throw new ArchiveError("Invalid XZ stream: variable-length integer is too long");
}
interface XzRecord {
unpaddedSize: number;
uncompressedSize: number;
}
interface XzStream {
start: number;
indexStart: number;
footerStart: number;View on GitHub (pinned to 9690622007)
Solutions
- Re-download the archive; a truncated tail cannot be recovered for indexed streams.
- Check that the index region passed to parseIndex matches the stream's actual backward size.
- Validate the file against checksums before parsing.
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the index region fits: last 12 bytes are footer, index backward size is in it
if (bytes.byteLength < 12) throw new Error("XZ stream too short to contain an index"); Try / catch
try {
const idx = parseIndex(bytes, indexOffset);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("truncated variable-length")) {
throw new Error("XZ index is truncated — file incomplete");
}
throw err;
} Prevention
- Validate the stream footer and backward size before parsing the index
- Re-download truncated files instead of parsing partial data
- Confirm the index offset/limit covers the full index region
When it happens
Trigger: Parsing index records (count, unpaddedSize, uncompressedSize) or block header fields (declaredCompressed, declaredUncompressed, filter id) where the cursor limit is hit mid-integer.
Common situations: Truncated .xz file cut off mid-index or mid-block-header; wrong limit passed to the index parser so the region ends inside a varint.
Related errors
- Invalid XZ stream: truncated integer
- Invalid XZ stream: non-canonical variable-length integer
- Invalid ARJ archive: truncated data
- Invalid XZ stream: padding without a stream
- Invalid XZ stream: truncated stream framing
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/821756618aeb8d5d.
Report an issue: GitHub.