can1357/oh-my-pi · error · ArchiveError
Invalid XZ BCJ filter 0x${filter.id.toString(16)} properties
Error message
Invalid XZ BCJ filter 0x${filter.id.toString(16)} properties What it means
Thrown while applying XZ block filters: BCJ branch/call/jump filters (x86, PowerPC, IA-64, ARM, SPARC, ARM64, RISC-V) must have either empty properties or exactly 4 bytes holding the little-endian start offset. The library throws when a BCJ filter's properties have any other byte length, indicating a malformed block header.
Source
Thrown at packages/utils/src/ar/codecs/xz.ts:376
}
const address = (read32BE(bytes, index + 4) - startOffset - index) >>> 0;
instruction2 = ((instruction >>> 12) | (address << 20)) >>> 0;
instruction = (0x17 | (register << 7) | ((address + 0x800) & 0xfffff000)) >>> 0;
}
write32LE(bytes, index, instruction);
write32LE(bytes, index + 4, instruction2);
index += 6;
}
}
function applyFilter(bytes: Uint8Array, filter: XzFilter): void {
if (filter.id === 3) {
if (filter.properties.byteLength !== 1) throw new ArchiveError("Invalid XZ Delta filter properties");
deltaDecode(bytes, filter.properties[0]! + 1);
return;
}
if (filter.properties.byteLength !== 0 && filter.properties.byteLength !== 4)
throw new ArchiveError(`Invalid XZ BCJ filter 0x${filter.id.toString(16)} properties`);
const startOffset = filter.properties.byteLength === 4 ? read32LE(filter.properties, 0) : 0;
const alignment = filter.id === 6 ? 16 : filter.id === 8 || filter.id === 11 ? 2 : filter.id === 4 ? 1 : 4;
if ((startOffset & (alignment - 1)) !== 0)
throw new ArchiveError(`Invalid XZ BCJ filter 0x${filter.id.toString(16)} start offset`);
switch (filter.id) {
case 4:
x86Decode(bytes, startOffset);
break;
case 5:
powerPcDecode(bytes, startOffset);
break;
case 6:
ia64Decode(bytes, startOffset);
break;
case 7:
armDecode(bytes, startOffset);
break;
case 8:View on GitHub (pinned to 9690622007)
Solutions
- Validate the archive externally (`xz -t`) and replace the corrupt file with a known-good copy
- Re-download or re-extract; check whether the transfer (FTP ascii mode, partial download) mangled the bytes
- Re-compress the data with the standard xz tool if the file came from a custom pipeline
- Wrap decode in error handling that reports 'corrupt archive' to the user rather than retrying the same bytes
Example fix
// before: truncated BCJ properties (2 bytes)
const filter = { id: 4, properties: new Uint8Array([0, 0]) };
// after: BCJ properties are empty or a 4-byte LE start offset
const filter = { id: 4, properties: new Uint8Array(4) }; Defensive patterns
Strategy: validation
Validate before calling
const t = await $`xz -t archive.xz`.quiet().nothrow();
if (t.exitCode !== 0) throw new Error('archive.xz fails XZ integrity validation'); Type guard
function isBcjFilter(f: { id: number; properties: Uint8Array }): boolean {
return f.id === 3 || f.properties.byteLength === 0 || f.properties.byteLength === 4;
} Try / catch
try {
await decodeXz(bytes);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes('Invalid XZ BCJ filter')) {
throw new Error(`Archive uses malformed BCJ filter properties: ${err.message}`);
}
throw err;
} Prevention
- Prefer default xz compression settings unless BCJ filters are specifically needed
- Verify files with an independent XZ implementation before decoding
- Detect truncation by comparing file size against a source-provided length
- Treat untrusted archives as fail-closed: reject on any structural ArchiveError
When it happens
Trigger: Decompressing an XZ stream whose block header declares a BCJ filter (id 4,5,6,8,9,10,11) with a properties blob of length 1, 2, 3, or >4 bytes.
Common situations: Corrupt or maliciously crafted archives; files produced by broken encoders; bit-flip corruption in the filter properties region of the block header.
Related errors
- Invalid XZ stream: padding without a stream
- Invalid XZ stream: backward index size is invalid
- Invalid XZ Delta filter properties
- Invalid XZ BCJ filter 0x${filter.id.toString(16)} start offs
- Invalid XZ stream: footer magic mismatch
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/174187ec20a94a8b.
Report an issue: GitHub.