paperclipai/paperclip · error · Error

Invalid zip archive: truncated before the central directory.

Error message

Invalid zip archive: truncated before the central directory.

What it means

Post-scan integrity check in readZipArchive. The sequential scan of local entries ran off the end of the buffer without ever reaching the central directory signature, meaning the upload was truncated at a record boundary. Fails closed so only a leading fragment is never imported as if it were the whole archive.

Source

Thrown at packages/shared/src/portability-zip.ts:285

        );
      }
      entries.push({
        path: archivePath,
        body: bytesToPortableFileEntry(archivePath, entryBytes),
      });
    }

    offset = bodyEnd;
  }

  // A complete archive always ends with a central directory after its local
  // entries. If the scan ran off the end of the buffer without reaching one, the
  // upload was truncated at a record boundary — fail closed rather than import a
  // leading fragment. Then fully validate the central directory the EOCD points
  // at so a truncated tail with a forged EOCD (whose count happens to match the
  // surviving entries) cannot smuggle in a partial import.
  if (!reachedCentralDirectory) {
    throw new Error("Invalid zip archive: truncated before the central directory.");
  }
  const eocdOffset = findEndOfCentralDirectoryOffset(bytes);
  if (eocdOffset === -1) {
    throw new Error("Invalid zip archive: missing end-of-central-directory record.");
  }
  validateCentralDirectory(bytes, eocdOffset, localHeaderCount);

  const rootPath = sharedArchiveRoot(entries.map((entry) => entry.path));
  const files: Record<string, CompanyPortabilityFileEntry> = {};
  for (const entry of entries) {
    const normalizedPath =
      rootPath && entry.path.startsWith(`${rootPath}/`)
        ? entry.path.slice(rootPath.length + 1)
        : entry.path;
    if (!normalizedPath) continue;
    // Two entries that normalize to the same path (e.g. `a/b` and `a//b`) make
    // the package ambiguous; reject it rather than silently letting the later
    // entry's contents win over the earlier one.

View on GitHub (pinned to 120ae5428f)

Solutions

  1. Re-download the complete archive; it ends before the central directory.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/shared/src/portability-zip.ts:285 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18). Data as JSON: /api/errors/ef7660ba55adabd3. Report an issue: GitHub.