{"record":{"id":"805e8ce867e48635","repo":"paperclipai/paperclip","slug":"invalid-zip-archive-central-directory-location-is","errorCode":null,"errorMessage":"Invalid zip archive: central directory location is inconsistent (truncated or forged).","messagePattern":"Invalid zip archive: central directory location is inconsistent \\(truncated or forged\\)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/portability-zip.ts","lineNumber":94,"sourceCode":"\n// Fully validate the central directory the EOCD advertises against the local\n// entries actually read from the archive body. Trusting only the EOCD's entry\n// count is not enough: a truncated archive with a forged 22-byte EOCD whose\n// count matches the surviving local entries would otherwise be accepted, and the\n// importer would silently process a partial company package (dropping agents,\n// issues, and so on). This walks the real central directory and requires that:\n//   • it is fully present and sits immediately before the EOCD (no gap, no\n//     pointer past the buffer — a truncated tail fails here);\n//   • every record carries the central-directory signature and its lengths sum\n//     to exactly the declared directory size; and\n//   • every record references a real local file header, and the record count\n//     equals both the EOCD's declared count and the local entries parsed.\nfunction validateCentralDirectory(bytes: Uint8Array, eocdOffset: number, localHeaderCount: number) {\n  const declaredEntryCount = readUint16(bytes, eocdOffset + 10);\n  const centralDirectorySize = readUint32(bytes, eocdOffset + 12);\n  const centralDirectoryStart = readUint32(bytes, eocdOffset + 16);\n  if (centralDirectoryStart > eocdOffset || centralDirectoryStart + centralDirectorySize !== eocdOffset) {\n    throw new Error(\n      \"Invalid zip archive: central directory location is inconsistent (truncated or forged).\",\n    );\n  }\n\n  const directoryEnd = centralDirectoryStart + centralDirectorySize;\n  let cursor = centralDirectoryStart;\n  let recordCount = 0;\n  while (cursor < directoryEnd) {\n    if (cursor + 46 > directoryEnd || readUint32(bytes, cursor) !== CENTRAL_DIRECTORY_SIGNATURE) {\n      throw new Error(\"Invalid zip archive: malformed central directory record.\");\n    }\n    const fileNameLength = readUint16(bytes, cursor + 28);\n    const extraFieldLength = readUint16(bytes, cursor + 30);\n    const commentLength = readUint16(bytes, cursor + 32);\n    const localHeaderOffset = readUint32(bytes, cursor + 42);\n    if (localHeaderOffset + 4 > bytes.length || readUint32(bytes, localHeaderOffset) !== LOCAL_FILE_SIGNATURE) {\n      throw new Error(\"Invalid zip archive: central directory references a missing local entry.\");\n    }","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/packages/shared/src/portability-zip.ts#L76-L112","documentation":"Error \"Invalid zip archive: central directory location is inconsistent (truncated or forged).\" thrown in paperclipai/paperclip.","triggerScenarios":"Thrown at packages/shared/src/portability-zip.ts:94 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Re-download or rebuild the zip archive; the file is truncated or forged."],"exampleFix":null,"handlingStrategy":null,"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"}