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
- Raise limits.maxCompressionRatio for trusted backups known to compress well.
- Reject the archive for untrusted sources; archive-level >2000x compression is rarely benign.
- 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
- Treat an archive-level ratio over 2000x as a zip-bomb for untrusted sources.
- Only raise the cap for your own exporter whose output you know compresses well.
- Combine with maxTotalUncompressedBytes as a second bound.
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
- ZIP entry compression ratio is unsafe: ${entry.name}
- ZIP contains too many entries
- ZIP entry is too large: ${entry.name}
- ZIP archive central directory is invalid
- Duplicate ZIP entry: ${entry.name}
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/ee62b495e5c0d372.
Report an issue: GitHub.