different-ai/openwork · error · Error

ZIP entry ${name} uses unsupported compression method ${meth

Error message

ZIP entry ${name} uses unsupported compression method ${method}.

What it means

After reading each central-directory entry's compression method, listZipEntries accepts only ZIP_STORED (0) and ZIP_DEFLATE (8). Any other method (bzip2, LZMA, AES-encrypted pseudo-methods, etc.) is rejected by name to keep the decompressor surface minimal and safe.

Source

Thrown at apps/server/src/opencode-plugins/openwork-office-attachments.ts:297

  const entries: ZipEntry[] = [];
  let cursor = centralOffset;
  let totalUncompressed = 0;
  for (let index = 0; index < count; index += 1) {
    if (cursor + 46 > centralEnd || buffer.readUInt32LE(cursor) !== ZIP_CENTRAL_DIRECTORY_HEADER) throw new Error("Invalid ZIP central directory entry.");
    const flags = buffer.readUInt16LE(cursor + 8);
    const method = buffer.readUInt16LE(cursor + 10);
    const compressedSize = buffer.readUInt32LE(cursor + 20);
    const uncompressedSize = buffer.readUInt32LE(cursor + 24);
    const nameLength = buffer.readUInt16LE(cursor + 28);
    const extraLength = buffer.readUInt16LE(cursor + 30);
    const commentLength = buffer.readUInt16LE(cursor + 32);
    const localOffset = buffer.readUInt32LE(cursor + 42);
    if (compressedSize === 0xffffffff || uncompressedSize === 0xffffffff || localOffset === 0xffffffff) throw new Error("ZIP64 archives are not supported.");
    if (cursor + 46 + nameLength + extraLength + commentLength > centralEnd) throw new Error("ZIP central directory entry is out of bounds.");
    const name = buffer.toString("utf8", cursor + 46, cursor + 46 + nameLength);
    rejectUnsafeZipFlags(flags, name);
    if (method !== ZIP_STORED && method !== ZIP_DEFLATE) throw new Error(`ZIP entry ${name} uses unsupported compression method ${method}.`);
    if (uncompressedSize > MAX_ENTRY_UNCOMPRESSED_BYTES) throw new Error(`ZIP entry ${name} exceeds per-entry uncompressed limit.`);
    if (uncompressedSize > 0 && compressedSize === 0) throw new Error(`ZIP entry ${name} has an invalid compression ratio.`);
    if (compressedSize > 0 && uncompressedSize / compressedSize > MAX_ZIP_COMPRESSION_RATIO) throw new Error(`ZIP entry ${name} exceeds compression ratio limit.`);
    totalUncompressed += uncompressedSize;
    if (totalUncompressed > MAX_TOTAL_UNCOMPRESSED_BYTES) throw new Error("ZIP archive exceeds total uncompressed limit.");
    entries.push({ name, flags, method, compressedSize, uncompressedSize, localOffset });
    cursor += 46 + nameLength + extraLength + commentLength;
  }
  if (cursor !== centralEnd) throw new Error("ZIP central directory size does not match its entries.");
  return entries;
}

function readZipEntryData(buffer: Buffer, entry: ZipEntry): Buffer {
  const cursor = entry.localOffset;
  if (cursor + 30 > buffer.byteLength || buffer.readUInt32LE(cursor) !== ZIP_LOCAL_FILE_HEADER) throw new Error(`Invalid local ZIP header for ${entry.name}.`);
  const localFlags = buffer.readUInt16LE(cursor + 6);
  const localMethod = buffer.readUInt16LE(cursor + 8);
  const localCompressedSize = buffer.readUInt32LE(cursor + 18);

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Re-create the archive with standard deflate compression: 'zip -Z deflate' or default 7-Zip/OS settings without encryption.
  2. Remove password/AES encryption from the archive before uploading.
  3. Re-export the office document from its native app (which writes deflate/store entries).
  4. Verify the method field is intact if the file is merely corrupted — get a fresh copy.

Example fix

// before
7z a -tlzma archive.zip doc.docx  // LZMA method -> rejected
// after
7z a -tzip archive.zip doc.docx   // deflate -> accepted
Defensive patterns

Strategy: try-catch

Validate before calling

import { unzip } from 'fflate'
// pre-flight with a standard parser to surface method errors early:
const files = unzipSync(buf) // throws on unsupported methods with a familiar message

Type guard

function isSupportedZipMethod(method: number): method is 0 | 8 {
  return method === 0 || method === 8
}

Try / catch

try {
  const entries = await extractOfficeAttachments(file)
} catch (e) {
  if (e instanceof Error && /unsupported compression method/.test(e.message)) {
    const m = /method (\d+)/.exec(e.message)?.[1]
    alertUser(`archive uses unsupported compression (method ${m}); re-zip with deflate, no encryption`)
  } else throw e
}

Prevention

When it happens

Trigger: Extracting an office attachment where an entry's central-directory method byte is not 0 or 8 — e.g. ZIP created with bzip2/LZMA compression, an AES-encrypted archive (method 99), or a corrupted method field.

Common situations: Files compressed with 'zip -Z bzip2' or 7-Zip's LZMA; password-protected/AES ZIPs from tools like 7-Zip; corrupted header bytes after truncation.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/16b0d1331f40ece5. Report an issue: GitHub.