{"record":{"id":"3a402f1eae08cc90","repo":"nexu-io/open-design","slug":"encrypted-zip-entries-are-not-supported","errorCode":null,"errorMessage":"encrypted zip entries are not supported","messagePattern":"encrypted zip entries are not supported","errorType":"validation","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/daemon/src/design/claude-design-import.ts","lineNumber":207,"sourceCode":"    throw new Error('invalid zip central directory');\n  }\n\n  const entries: ZipEntry[] = [];\n  let offset = centralOffset;\n  for (let i = 0; i < entryCount; i += 1) {\n    if (zip.readUInt32LE(offset) !== CENTRAL_SIG) {\n      throw new Error('invalid zip central directory entry');\n    }\n    const flags = zip.readUInt16LE(offset + 8);\n    const method = zip.readUInt16LE(offset + 10);\n    const compressedSize = zip.readUInt32LE(offset + 20);\n    const uncompressedSize = zip.readUInt32LE(offset + 24);\n    const nameLen = zip.readUInt16LE(offset + 28);\n    const extraLen = zip.readUInt16LE(offset + 30);\n    const commentLen = zip.readUInt16LE(offset + 32);\n    const localOffset = zip.readUInt32LE(offset + 42);\n    const name = zip.slice(offset + 46, offset + 46 + nameLen).toString('utf8');\n    if ((flags & 1) !== 0) throw new Error('encrypted zip entries are not supported');\n    if (method !== 0 && method !== 8) {\n      throw new Error(`unsupported zip compression method: ${method}`);\n    }\n    entries.push({\n      name,\n      method,\n      compressedSize,\n      uncompressedSize,\n      localOffset,\n      isDirectory: name.endsWith('/'),\n    });\n    offset += 46 + nameLen + extraLen + commentLen;\n  }\n  return entries;\n}\n\nfunction findEndOfCentralDirectory(zip: Buffer): number {\n  const min = Math.max(0, zip.length - 0xffff - 22);","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/design/claude-design-import.ts#L189-L225","documentation":"The general-purpose bit-flag's bit 0 (read from offset+8 at line 198) marks the entry as encrypted. The importer supports only unencrypted stored (method 0) and deflate (method 8) entries, so any encrypted entry aborts the import. Maps to HTTP 400 via the /api/import/claude-design route.","triggerScenarios":"Uploading a password-protected or AES/ZipCrypto-encrypted zip to POST /api/import/claude-design; readCentralDirectory parses each entry and (flags & 1) !== 0 fails on the first encrypted entry.","commonSituations":"The user re-archived an export with encryption enabled; corporate archiving defaults that apply encryption; a shared/protected zip; macOS 'Encrypt' option or 7-Zip AES.","solutions":["Re-export the Claude Design project without encryption.","Unzip the protected archive locally (supplying the password) and re-zip the result with no password.","Disable encryption in the archiving tool and recreate the zip."],"exampleFix":"// before: archive created with encryption\n//   zip --password secret export.zip design-canvas.jsx\n// after: plain deflate archive\n//   zip export.zip design-canvas.jsx","handlingStrategy":"validation","validationCode":"// Detect encryption by reading general-purpose bit flag bit 0 of each\n// central-directory entry before importing.\nimport { openSync, readSync } from 'node:fs';\nfunction zipHasEncryptedEntries(file: string): boolean {\n  // Cheap heuristic: `unzip -l` annotates encrypted entries; fall back to\n  // a dedicated zip reader (yauzl) for a precise per-entry check.\n  try {\n    const out = execFileSync('unzip', ['-l', file], { encoding: 'utf8' });\n    return /Encrypted|~/.test(out); // unzip marks encrypted entries\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await importClaudeDesignZip(zipPath, projectDir);\n} catch (err) {\n  if (String(err).includes('encrypted')) {\n    return res.status(400).json({ error: 'encrypted zips are not supported' });\n  }\n  throw err;\n}","preventionTips":["Re-create archives without a password before upload.","Document for users that the importer supports only unencrypted deflate/stored zips.","Reject encrypted archives at the upload UI with a clear message."],"tags":["zip","encryption","security","import","claude-design"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}