{"record":{"id":"5850b5fa975b780d","repo":"paperclipai/paperclip","slug":"invalid-zip-archive-missing-end-of-central-direct","errorCode":null,"errorMessage":"Invalid zip archive: missing end-of-central-directory record.","messagePattern":"Invalid zip archive: missing end-of-central-directory record\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/portability-zip.ts","lineNumber":289,"sourceCode":"        body: bytesToPortableFileEntry(archivePath, entryBytes),\n      });\n    }\n\n    offset = bodyEnd;\n  }\n\n  // A complete archive always ends with a central directory after its local\n  // entries. If the scan ran off the end of the buffer without reaching one, the\n  // upload was truncated at a record boundary — fail closed rather than import a\n  // leading fragment. Then fully validate the central directory the EOCD points\n  // at so a truncated tail with a forged EOCD (whose count happens to match the\n  // surviving entries) cannot smuggle in a partial import.\n  if (!reachedCentralDirectory) {\n    throw new Error(\"Invalid zip archive: truncated before the central directory.\");\n  }\n  const eocdOffset = findEndOfCentralDirectoryOffset(bytes);\n  if (eocdOffset === -1) {\n    throw new Error(\"Invalid zip archive: missing end-of-central-directory record.\");\n  }\n  validateCentralDirectory(bytes, eocdOffset, localHeaderCount);\n\n  const rootPath = sharedArchiveRoot(entries.map((entry) => entry.path));\n  const files: Record<string, CompanyPortabilityFileEntry> = {};\n  for (const entry of entries) {\n    const normalizedPath =\n      rootPath && entry.path.startsWith(`${rootPath}/`)\n        ? entry.path.slice(rootPath.length + 1)\n        : entry.path;\n    if (!normalizedPath) continue;\n    // Two entries that normalize to the same path (e.g. `a/b` and `a//b`) make\n    // the package ambiguous; reject it rather than silently letting the later\n    // entry's contents win over the earlier one.\n    if (Object.prototype.hasOwnProperty.call(files, normalizedPath)) {\n      throw new Error(`Invalid zip archive: duplicate entry path \"${normalizedPath}\".`);\n    }\n    files[normalizedPath] = entry.body;","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/packages/shared/src/portability-zip.ts#L271-L307","documentation":"Signature-scan failure in readZipArchive's EOCD lookup (findEndOfCentralDirectoryOffset returned -1): no end-of-central-directory record exists anywhere in the bytes. Without the EOCD there is no authoritative entry count, so the buffer is not a complete zip archive and is rejected before central-directory validation.","triggerScenarios":"Thrown at packages/shared/src/portability-zip.ts:289 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Re-create/re-download the archive; the end-of-central-directory record is missing."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}