can1357/oh-my-pi · error · ArchiveError
Invalid XZ Delta filter properties
Error message
Invalid XZ Delta filter properties
What it means
This ArchiveError is thrown while applying the filters of an XZ block during decompression. Filter ID 3 is the Delta filter; per the XZ spec its properties must be exactly one byte (the distance minus 1). The library throws when the Delta filter's properties field has any other byte length, meaning the stream's filter properties are malformed.
Source
Thrown at packages/utils/src/ar/codecs/xz.ts:371
} else {
const register = instruction >>> 27;
if (((instruction - 0x3117) << 18) >>> 0 >= (register & 0x1d)) {
index += 2;
continue;
}
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);View on GitHub (pinned to 9690622007)
Solutions
- Verify the source file is a valid XZ archive (test with `xz -t file.xz` or an equivalent tool) and re-obtain it if corrupt
- Check for truncation: compare file size against the expected size or re-download/re-extract the archive
- Confirm the producing tool is a spec-compliant XZ encoder; re-compress with standard xz if it was generated in-house
- If the input is untrusted, treat this as expected rejection and surface a clear user-facing 'corrupt archive' message
Example fix
// before: properties encoded with wrong length
const filter = { id: 3, properties: new Uint8Array([4, 0]) };
// after: Delta filter must carry exactly 1 property byte (distance - 1)
const filter = { id: 3, properties: new Uint8Array([3]) }; // distance = 4 Defensive patterns
Strategy: validation
Validate before calling
// Inspect block filter properties before decode, or validate the archive externally first
import { $ } from 'bun';
const t = await $`xz -t archive.xz`.quiet().nothrow();
if (t.exitCode !== 0) throw new Error('archive.xz is not a valid XZ stream'); Type guard
function isDeltaFilter(f: { id: number; properties: Uint8Array }): boolean {
return f.id !== 3 || f.properties.byteLength === 1;
} Try / catch
import { ArchiveError } from '@oh-my-pi/pi-utils/ar/codecs';
try {
await decodeXz(bytes);
} catch (err) {
if (err instanceof ArchiveError && err.message.startsWith('Invalid XZ Delta filter')) {
throw new Error('Archive is corrupt: malformed Delta filter properties');
}
throw err;
} Prevention
- Only decode XZ files produced by spec-compliant encoders (standard xz tool)
- Verify archives with `xz -t` before programmatic decode in pipelines
- Never hand-edit filter property bytes in compressed files
- Validate file completeness (size/checksum from source) before decoding
When it happens
Trigger: Decompressing an XZ stream whose block header declares a Delta filter (id 3) with a properties blob that is 0 bytes or more than 1 byte — i.e. the encoded properties size byte in the block header disagrees with the XZ spec.
Common situations: Corrupt or truncated archive files; hand-crafted or fuzzed XZ input; files produced by non-conformant compressors; byte-level corruption from a bad transfer or storage medium.
Related errors
- Invalid XZ stream: padding without a stream
- Invalid XZ stream: backward index size is invalid
- Invalid XZ BCJ filter 0x${filter.id.toString(16)} properties
- Invalid XZ stream: footer magic mismatch
- Invalid XZ stream: footer CRC32 mismatch
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/da6246e686e75ea9.
Report an issue: GitHub.