{"record":{"id":"151c318002177236","repo":"nexu-io/open-design","slug":"zip-entry-size-mismatch-relpath","errorCode":null,"errorMessage":"zip entry size mismatch: ${relPath}","messagePattern":"zip entry size mismatch: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/daemon/src/design/claude-design-import.ts","lineNumber":48,"sourceCode":"\n  for (const entry of entries) {\n    if (entry.isDirectory) continue;\n    if (files.length >= MAX_FILES) throw new Error('zip contains too many files');\n    const relPath = sanitizeZipPath(entry.name);\n    if (entry.uncompressedSize > MAX_FILE_BYTES) {\n      throw new Error(`zip file too large: ${relPath}`);\n    }\n\n    // Decode first; the central directory's uncompressedSize is unreliable for\n    // streaming/data-descriptor zips (it can read 0 even when the payload\n    // carries real data). The inflate cap and the post-decode size checks below\n    // are authoritative.\n    const body = readEntryBody(zip, entry);\n    if (body.length > MAX_FILE_BYTES) {\n      throw new Error(`zip file too large: ${relPath}`);\n    }\n    if (entry.uncompressedSize > 0 && body.length !== entry.uncompressedSize) {\n      throw new Error(`zip entry size mismatch: ${relPath}`);\n    }\n    totalBytes += body.length;\n    if (totalBytes > MAX_TOTAL_BYTES) throw new Error('zip is too large');\n\n    files.push({ path: relPath, body: normalizeImportedClaudeDesignFile(relPath, body) });\n  }\n\n  if (files.length === 0) throw new Error('zip contains no files');\n  const entryFile = chooseEntryFile(files.map((f) => f.path));\n  if (!entryFile) throw new Error('zip does not contain an HTML file');\n\n  const dirCreates = new Map<string, Promise<string | undefined>>();\n  const ensureDir = (dir: string) => {\n    let pending = dirCreates.get(dir);\n    if (!pending) {\n      pending = mkdir(dir, { recursive: true });\n      dirCreates.set(dir, pending);\n    }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/design/claude-design-import.ts#L30-L66","documentation":"Thrown by `importClaudeDesignZip` when an entry's central-directory-declared `uncompressedSize` is greater than 0 but does not equal the actual decoded body length. This catches truncated, corrupt, or tampered entries where the declared size and the real payload disagree.","triggerScenarios":"A zip entry whose declared uncompressed size is, say, 1024 bytes but whose decoded body is a different length. Causes include a truncated download, a corrupt archive, a tampered central directory, or a zip produced by a buggy writer.","commonSituations":"The archive was partially downloaded or transferred. Disk corruption. A zip writer bug. An attacker altering the central directory to disguise a large payload.","solutions":["Re-obtain the zip from the original source (re-export or re-download) to rule out truncation/corruption.","Verify the archive with a standard unzip tool; if it reports an error, the archive is corrupt.","If you produce the archive, ensure the writer emits correct uncompressed sizes."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for (const entry of entries.filter((e) => !e.isDirectory && e.uncompressedSize > 0)) {\n  const body = readEntryBody(zip, entry);\n  if (body.length !== entry.uncompressedSize) {\n    throw new Error(`entry \"${entry.name}\" decoded size ${body.length} != declared ${entry.uncompressedSize}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await importClaudeDesignZip(zipPath, projectDir);\n} catch (err) {\n  if (err instanceof Error && /^zip entry size mismatch:/.test(err.message)) {\n    // re-obtain the archive; it is corrupt or truncated\n  }\n  throw err;\n}","preventionTips":["Re-obtain archives from the original source to avoid truncation/corruption.","Verify archives with a standard unzip tool before importing.","Use a reliable zip writer that emits correct uncompressed sizes."],"tags":["zip","claude-design","validation","data-integrity","import"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}