chatboxai/chatbox · error
ZIP contains too many entries
Error message
ZIP contains too many entries
What it means
Thrown after incrementing entryCount when it exceeds limits.maxEntries (default 100,004 from DEFAULT_ZIP_LIMITS). It is a zip-bomb / resource-exhaustion guard that aborts streaming before the archive can enumerate an attacker-controlled or pathologically large number of entries.
Source
Thrown at src/renderer/packages/backup/zip.ts:227
onEntry: (entry: ReadZipEntry) => Promise<void> | void,
options: ZipReadOptions = {}
): Promise<void> {
await validateZipEndOfCentralDirectory(file)
const limits = { ...DEFAULT_ZIP_LIMITS, ...options.limits }
const seenPaths = new Set<string>()
const pendingHandlers: Promise<void>[] = []
let entryCount = 0
let totalUncompressedBytes = 0
let fatalError: unknown
const unzip = new Unzip((entry) => {
try {
throwIfAborted(options.signal)
assertSafeArchivePath(entry.name)
if (seenPaths.has(entry.name)) throw new Error(`Duplicate ZIP entry: ${entry.name}`)
seenPaths.add(entry.name)
entryCount++
if (entryCount > limits.maxEntries) throw new Error('ZIP contains too many entries')
const entryLimits = { ...limits, ...options.entryLimits?.(entry.name) }
if (entry.originalSize !== undefined && entry.originalSize > entryLimits.maxEntryUncompressedBytes) {
throw new Error(`ZIP entry is too large: ${entry.name}`)
}
if (
entry.size !== undefined &&
entry.originalSize !== undefined &&
entry.originalSize > 1024 * 1024 &&
entry.originalSize > Math.max(1, entry.size) * entryLimits.maxCompressionRatio
) {
throw new Error(`ZIP entry compression ratio is unsafe: ${entry.name}`)
}
const chunks: Uint8Array[] = []
let entryBytes = 0
entry.ondata = (error, data, final) => {
if (fatalError) return
if (error) {View on GitHub (pinned to 81571269ad)
Solutions
- Pass a higher limits.maxEntries in ZipReadOptions if the archive is trusted and known large.
- Re-export the backup excluding unnecessary tiny files to shrink the entry count.
- Keep the default cap for untrusted imports and surface a clear 'too many files' message to the user.
Example fix
// before
await readZipFileEntries(file, onEntry)
// after: raise the cap for trusted full backups
await readZipFileEntries(file, onEntry, {
limits: { maxEntries: 500_000 }
}) Defensive patterns
Strategy: validation
Validate before calling
// Configure the cap to match the trusted archive's known entry count.
const options: ZipReadOptions = {
limits: { maxEntries: 500_000 }, // raise for trusted full backups
}
await readZipFileEntries(file, onEntry, options) Try / catch
try {
await readZipFileEntries(file, onEntry, { limits: { maxEntries } })
} catch (error) {
if (error instanceof Error && error.message === 'ZIP contains too many entries') {
// Either raise the cap (trusted) or reject (untrusted).
} else throw error
} Prevention
- Pick limits.maxEntries based on whether the source is trusted (your exporter) or untrusted (user upload).
- Keep the conservative default for untrusted imports and surface a clear message.
- Exclude unnecessary tiny files (e.g. node_modules) at export time to keep entry counts sane.
When it happens
Trigger: An archive with more than 100,004 entries, or with more than a caller-lowered maxEntries. Trips as soon as the (entryCount+1)-th entry callback fires.
Common situations: Legitimate large backups (e.g. node_modules or many small chat-attachment files) that breach the default, hostile test archives, or an integration that set limits.maxEntries too low.
Related errors
- ZIP entry is too large: ${entry.name}
- ZIP entry compression ratio is unsafe: ${entry.name}
- ZIP archive compression ratio is unsafe
- Backup JSON entry is too large: ${path}
- Backup contains too many entries
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/3f7717a29cdac016.
Report an issue: GitHub.