{"record":{"id":"5438723b5f83f868","repo":"nexu-io/open-design","slug":"zip-entry-exceeds-archive-entry-name","errorCode":null,"errorMessage":"zip entry exceeds archive: ${entry.name}","messagePattern":"zip entry exceeds archive: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/daemon/src/design/claude-design-import.ts","lineNumber":241,"sourceCode":"\nfunction findEndOfCentralDirectory(zip: Buffer): number {\n  const min = Math.max(0, zip.length - 0xffff - 22);\n  for (let i = zip.length - 22; i >= min; i -= 1) {\n    if (zip.readUInt32LE(i) === EOCD_SIG) return i;\n  }\n  throw new Error('invalid zip: missing central directory');\n}\n\nfunction readEntryBody(zip: Buffer, entry: ZipEntry): Buffer {\n  const offset = entry.localOffset;\n  if (zip.readUInt32LE(offset) !== LOCAL_SIG) {\n    throw new Error(`invalid zip local header: ${entry.name}`);\n  }\n  const nameLen = zip.readUInt16LE(offset + 26);\n  const extraLen = zip.readUInt16LE(offset + 28);\n  const bodyStart = offset + 30 + nameLen + extraLen;\n  const bodyEnd = bodyStart + entry.compressedSize;\n  if (bodyEnd > zip.length) throw new Error(`zip entry exceeds archive: ${entry.name}`);\n  const compressed = zip.slice(bodyStart, bodyEnd);\n  if (entry.method === 0) return Buffer.from(compressed);\n  // A genuinely empty deflate payload would still occupy at least the BFINAL\n  // marker; an entirely missing payload cannot be inflated, so treat it as\n  // empty rather than handing a zero-length buffer to zlib.\n  if (compressed.length === 0) return Buffer.alloc(0);\n  // When the central directory advertises 0 (streaming zips with data\n  // descriptors), fall back to the per-file ceiling so legitimate non-empty\n  // payloads decode instead of being silently truncated. The post-decode\n  // checks in the caller enforce MAX_FILE_BYTES and total-bytes limits.\n  const cap = entry.uncompressedSize > 0 ? entry.uncompressedSize : MAX_FILE_BYTES;\n  return inflateRawSync(compressed, { maxOutputLength: cap });\n}\n\nfunction sanitizeZipPath(name: string): string {\n  if (name.includes('\\0')) throw new Error('invalid zip file name');\n  if (/^[A-Za-z]:/.test(name) || name.startsWith('/')) {\n    throw new Error('absolute zip paths are not allowed');","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/design/claude-design-import.ts#L223-L259","documentation":"readEntryBody computes bodyEnd = bodyStart + entry.compressedSize and rejects when bodyEnd > zip.length. The central directory declared a compressed size that would read past the end of the archive. Maps to HTTP 400.","triggerScenarios":"A central-directory entry whose compressedSize field points beyond the archive boundary: a truncated archive, a central directory copied from a larger original, or a data-descriptor/streaming zip whose sizes are inconsistent with the buffer.","commonSituations":"Partial download of the zip; truncation during multipart upload; archive truncated by a proxy/CDN with a size cap; an interrupted `zip` operation.","solutions":["Re-download or re-export the zip fully and verify the byte size matches the source.","Retry the upload over a stable connection.","Run `unzip -t file.zip` locally to confirm integrity before uploading."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Compare received file size to the source and run an integrity test.\nimport { statSync } from 'node:fs';\nimport { execFileSync } from 'node:child_process';\nfunction zipIntact(file: string): boolean {\n  if (statSync(file).size === 0) return false;\n  try { execFileSync('unzip', ['-tqq', file], { stdio: 'ignore' }); return true; }\n  catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await importClaudeDesignZip(zipPath, projectDir);\n} catch (err) {\n  if (String(err).includes('exceeds archive')) {\n    return res.status(400).json({ error: 'zip is truncated; re-download fully' });\n  }\n  throw err;\n}","preventionTips":["Verify uploaded byte size equals the source size before importing.","Use stable connections for large uploads; retry on truncation.","Run `unzip -t` to detect size/offset inconsistencies."],"tags":["zip","truncation","validation","import","claude-design"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}