chatboxai/chatbox · error

ZIP entry is too large: ${entry.name}

Error message

ZIP entry is too large: ${entry.name}

What it means

Thrown when an entry declares entry.originalSize greater than entryLimits.maxEntryUncompressedBytes (default 512 MiB). entryLimits is the global limit optionally narrowed per-path via options.entryLimits(name). The check uses the header-declared uncompressed size, so it aborts before inflating the payload.

Source

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

  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) {
          fatalError = error
          return
        }

View on GitHub (pinned to 81571269ad)

Solutions

  1. If large entries are expected for specific paths, raise the cap via options.entryLimits for those paths.
  2. Raise limits.maxEntryUncompressedBytes globally for trusted full backups.
  3. Exclude oversized blobs from the export on the producer side.

Example fix

// before
await readZipFileEntries(file, onEntry)

// after: allow large media paths while keeping the default elsewhere
await readZipFileEntries(file, onEntry, {
  entryLimits: (path) =>
    path.startsWith('attachments/')
      ? { maxEntryUncompressedBytes: 2 * 1024 * 1024 * 1024 }
      : {}
})
Defensive patterns

Strategy: validation

Validate before calling

// Raise the per-entry cap globally or per-path via entryLimits.
await readZipFileEntries(file, onEntry, {
  limits: { maxEntryUncompressedBytes: 2 * 1024 * 1024 * 1024 },
  entryLimits: (path) =>
    path.startsWith('attachments/')
      ? { maxEntryUncompressedBytes: 4 * 1024 * 1024 * 1024 }
      : {},
})

Try / catch

try {
  await readZipFileEntries(file, onEntry, opts)
} catch (error) {
  if (error instanceof Error && error.message.startsWith('ZIP entry is too large')) {
    reportToUser('One file in the backup exceeds the size limit.')
  } else throw error
}

Prevention

When it happens

Trigger: A single entry whose declared uncompressed size exceeds 512 MiB (or a per-path override), or an archive containing a large media blob/log that the backup importer does not expect.

Common situations: Backups bundling large video/attachment files, a single huge log/database blob, or a zip-bomb entry sized to exhaust memory.

Related errors


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