chatboxai/chatbox · error

ZIP archive compression ratio is unsafe

Error message

ZIP archive compression ratio is unsafe

What it means

Whole-archive zip-bomb guard evaluated after all entries have streamed: thrown when totalUncompressedBytes exceeds 1 MiB AND exceeds Math.max(1, file.size) * limits.maxCompressionRatio (default 2000x). Unlike the per-entry check, this uses the cumulative decompressed byte count tracked across every entry's ondata chunks.

Source

Thrown at src/renderer/packages/backup/zip.ts:301

  try {
    while (true) {
      throwIfAborted(options.signal)
      const { done, value } = await reader.read()
      if (done) {
        unzip.push(EMPTY_BYTES, true)
        break
      }
      unzip.push(value)
      if (fatalError) throw fatalError
      if (pendingHandlers.length > 0) await Promise.all(pendingHandlers.splice(0))
    }
    if (fatalError) throw fatalError
    if (pendingHandlers.length > 0) await Promise.all(pendingHandlers.splice(0))
    if (
      totalUncompressedBytes > 1024 * 1024 &&
      totalUncompressedBytes > Math.max(1, file.size) * limits.maxCompressionRatio
    ) {
      throw new Error('ZIP archive compression ratio is unsafe')
    }
  } finally {
    await reader.cancel().catch(() => undefined)
  }
}

View on GitHub (pinned to 81571269ad)

Solutions

  1. Raise limits.maxCompressionRatio for trusted backups known to compress well.
  2. Reject the archive for untrusted sources; archive-level >2000x compression is rarely benign.
  3. Re-export excluding redundant/highly-compressible payloads.

Example fix

// before
await readZipFileEntries(file, onEntry)

// after: raise the archive-level ratio cap for a trusted source
await readZipFileEntries(file, onEntry, {
  limits: { maxCompressionRatio: 5_000 }
})
Defensive patterns

Strategy: validation

Validate before calling

// Raise the archive-level ratio cap for a trusted, highly-compressible source.
await readZipFileEntries(file, onEntry, {
  limits: { maxCompressionRatio: 5_000 },
})

Try / catch

try {
  await readZipFileEntries(file, onEntry, opts)
} catch (error) {
  if (error instanceof Error && error.message === 'ZIP archive compression ratio is unsafe') {
    reportToUser('This archive is likely a zip-bomb and was rejected.')
  } else throw error
}

Prevention

When it happens

Trigger: An archive whose aggregate decompressed size is >2000x its on-disk size, achievable via many moderate-ratio entries that each pass the per-entry check, or a single entry that narrowly skirted it.

Common situations: Multi-entry zip-bombs, archives of highly compressible generated data, or backups of sparse virtual-disk images.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/ee62b495e5c0d372. Report an issue: GitHub.