nexu-io/open-design · error · Error
zip is too large
Error message
zip is too large
What it means
Thrown by `importClaudeDesignZip` when the running cumulative total of decoded entry body lengths exceeds `MAX_TOTAL_BYTES` (100 MiB). This is the aggregate zip-bomb guard, evaluated after each entry is decoded and added to the running total.
Source
Thrown at apps/daemon/src/design/claude-design-import.ts:51
if (files.length >= MAX_FILES) throw new Error('zip contains too many files');
const relPath = sanitizeZipPath(entry.name);
if (entry.uncompressedSize > MAX_FILE_BYTES) {
throw new Error(`zip file too large: ${relPath}`);
}
// Decode first; the central directory's uncompressedSize is unreliable for
// streaming/data-descriptor zips (it can read 0 even when the payload
// carries real data). The inflate cap and the post-decode size checks below
// are authoritative.
const body = readEntryBody(zip, entry);
if (body.length > MAX_FILE_BYTES) {
throw new Error(`zip file too large: ${relPath}`);
}
if (entry.uncompressedSize > 0 && body.length !== entry.uncompressedSize) {
throw new Error(`zip entry size mismatch: ${relPath}`);
}
totalBytes += body.length;
if (totalBytes > MAX_TOTAL_BYTES) throw new Error('zip is too large');
files.push({ path: relPath, body: normalizeImportedClaudeDesignFile(relPath, body) });
}
if (files.length === 0) throw new Error('zip contains no files');
const entryFile = chooseEntryFile(files.map((f) => f.path));
if (!entryFile) throw new Error('zip does not contain an HTML file');
const dirCreates = new Map<string, Promise<string | undefined>>();
const ensureDir = (dir: string) => {
let pending = dirCreates.get(dir);
if (!pending) {
pending = mkdir(dir, { recursive: true });
dirCreates.set(dir, pending);
}
return pending;
};
View on GitHub (pinned to 5be4028344)
Solutions
- Trim the archive contents so the total decoded size is at or below 100 MiB.
- Exclude bulky directories and externalize large media.
- Re-export selecting only the HTML and essential assets.
Defensive patterns
Strategy: validation
Validate before calling
const MAX_TOTAL_BYTES = 100 * 1024 * 1024;
let total = 0;
for (const entry of entries.filter((e) => !e.isDirectory)) {
total += readEntryBody(zip, entry).length;
if (total > MAX_TOTAL_BYTES) {
throw new Error(`archive total ${total} exceeds 100 MiB cap`);
}
} Try / catch
try {
await importClaudeDesignZip(zipPath, projectDir);
} catch (err) {
if (err instanceof Error && err.message === 'zip is too large') {
// trim aggregate archive size below 100 MiB and re-upload
}
throw err;
} Prevention
- Keep total archive content under 100 MiB.
- Exclude bulky directories and externalize large media before zipping.
- Pre-scan aggregate decoded size before importing.
When it happens
Trigger: An archive whose combined decoded entries exceed 100 MiB — e.g. many medium-sized files, or a few files that individually pass the 25 MiB per-file cap but together exceed the total.
Common situations: A legitimate but large export bundling many assets. An archive that includes bulky directories (`node_modules`, `dist`, media libraries). A zip bomb designed to pass per-file checks but blow the aggregate budget.
Related errors
- zip contains too many files
- zip file too large: ${relPath}
- zip entry size mismatch: ${relPath}
- zip contains no files
- zip does not contain an HTML file
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/cd3c956a4b7f9fdb.
Report an issue: GitHub.