{"record":{"id":"7b897c24681b0606","repo":"paperclipai/paperclip","slug":"invalid-zip-archive-duplicate-entry-path-norma","errorCode":null,"errorMessage":"Invalid zip archive: duplicate entry path \"${normalizedPath}\".","messagePattern":"Invalid zip archive: duplicate entry path \"(.+?)\"\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/portability-zip.ts","lineNumber":305,"sourceCode":"  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;\n  }\n\n  return { rootPath, files };\n}\n","sourceCodeStart":287,"sourceCodeEnd":312,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/packages/shared/src/portability-zip.ts#L287-L312","documentation":"Duplicate-path guard in readZipArchive: after stripping the shared archive root, two entries normalize to the same relative path. Since entries are collected into a Record keyed by path, a duplicate would silently overwrite earlier content (a classic zip-slip/confusion vector), so the import aborts instead.","triggerScenarios":"Thrown at packages/shared/src/portability-zip.ts:305 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove duplicate entry paths from the archive before uploading."],"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-14T05:17:10.506Z"}