nexu-io/open-design · error · Error
encrypted zip entries are not supported
Error message
encrypted zip entries are not supported
What it means
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.
Source
Thrown at apps/daemon/src/design/claude-design-import.ts:207
throw new Error('invalid zip central directory');
}
const entries: ZipEntry[] = [];
let offset = centralOffset;
for (let i = 0; i < entryCount; i += 1) {
if (zip.readUInt32LE(offset) !== CENTRAL_SIG) {
throw new Error('invalid zip central directory entry');
}
const flags = zip.readUInt16LE(offset + 8);
const method = zip.readUInt16LE(offset + 10);
const compressedSize = zip.readUInt32LE(offset + 20);
const uncompressedSize = zip.readUInt32LE(offset + 24);
const nameLen = zip.readUInt16LE(offset + 28);
const extraLen = zip.readUInt16LE(offset + 30);
const commentLen = zip.readUInt16LE(offset + 32);
const localOffset = zip.readUInt32LE(offset + 42);
const name = zip.slice(offset + 46, offset + 46 + nameLen).toString('utf8');
if ((flags & 1) !== 0) throw new Error('encrypted zip entries are not supported');
if (method !== 0 && method !== 8) {
throw new Error(`unsupported zip compression method: ${method}`);
}
entries.push({
name,
method,
compressedSize,
uncompressedSize,
localOffset,
isDirectory: name.endsWith('/'),
});
offset += 46 + nameLen + extraLen + commentLen;
}
return entries;
}
function findEndOfCentralDirectory(zip: Buffer): number {
const min = Math.max(0, zip.length - 0xffff - 22);View on GitHub (pinned to 5be4028344)
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.
Example fix
// before: archive created with encryption // zip --password secret export.zip design-canvas.jsx // after: plain deflate archive // zip export.zip design-canvas.jsx
Defensive patterns
Strategy: validation
Validate before calling
// Detect encryption by reading general-purpose bit flag bit 0 of each
// central-directory entry before importing.
import { openSync, readSync } from 'node:fs';
function zipHasEncryptedEntries(file: string): boolean {
// Cheap heuristic: `unzip -l` annotates encrypted entries; fall back to
// a dedicated zip reader (yauzl) for a precise per-entry check.
try {
const out = execFileSync('unzip', ['-l', file], { encoding: 'utf8' });
return /Encrypted|~/.test(out); // unzip marks encrypted entries
} catch {
return false;
}
} Try / catch
try {
await importClaudeDesignZip(zipPath, projectDir);
} catch (err) {
if (String(err).includes('encrypted')) {
return res.status(400).json({ error: 'encrypted zips are not supported' });
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- zip contains too many files
- zip file too large: ${relPath}
- zip entry size mismatch: ${relPath}
- zip is too large
- zip contains no files
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/3a402f1eae08cc90.
Report an issue: GitHub.