chatboxai/chatbox · error

Duplicate ZIP entry: ${entry.path}

Error message

Duplicate ZIP entry: ${entry.path}

What it means

Thrown by createZipStream's producer when an incoming entry's path has already been seen in the same archive. A ZIP central directory can technically allow duplicate names but extraction/restore semantics break, so the stream rejects duplicates up front.

Source

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

      return
    }
    if (data.length > 0) {
      queue.push(data)
      queuedBytes += data.length
    }
    if (final) outputComplete = true
    notifyConsumer()
  })

  const onAbort = () => zip.terminate()
  signal?.addEventListener('abort', onAbort, { once: true })

  void (async () => {
    try {
      for await (const entry of entries) {
        throwIfAborted(signal)
        assertSafeArchivePath(entry.path)
        if (seenPaths.has(entry.path)) throw new Error(`Duplicate ZIP entry: ${entry.path}`)
        seenPaths.add(entry.path)
        const file =
          entry.compress === false ? new ZipPassThrough(entry.path) : new ZipDeflate(entry.path, { level: 6 })
        zip.add(file)
        let pushed = false
        for await (const chunk of toChunks(entry.data)) {
          throwIfAborted(signal)
          if (chunk.length === 0) continue
          if (pushed) {
            file.push(chunk)
          } else {
            file.push(chunk)
            pushed = true
          }
          await waitForDrain()
        }
        file.push(EMPTY_BYTES, true)
        await waitForDrain()

View on GitHub (pinned to 81571269ad)

Solutions

  1. Dedupe entries by path before streaming them into createZipStream.
  2. Namespace paths per entry type (e.g. 'sessions/<id>.json', 'resources/<id>').
  3. Audit the producer that builds the entry list.

Example fix

// before
yield* allEntries // may contain duplicate paths

// after
const seen = new Set<string>()
for (const e of allEntries) {
  if (seen.has(e.path)) continue
  seen.add(e.path)
  yield e
}
Defensive patterns

Strategy: validation

Validate before calling

function findDuplicateEntryPaths(entries: Iterable<ZipArchiveEntry>): string[] {
  const seen = new Set<string>()
  const dups = new Set<string>()
  for (const e of entries) (seen.has(e.path) ? dups : seen).add(e.path)
  return [...dups]
}

Try / catch

try {
  for await (const chunk of createZipStream(entries, signal)) writeChunk(chunk)
} catch (error) {
  if (/Duplicate ZIP entry/.test((error as Error).message)) reportDuplicatePaths(error)
  throw error
}

Prevention

When it happens

Trigger: Two entries passed to createZipStream share the same path string.

Common situations: Export pipeline emits the same file path twice (e.g. a resource and a session both written to 'data/x.json'); case-only duplicates on case-insensitive systems; a merge without dedupe.

Related errors


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