TryGhost/Ghost · warning · ThemeArchiveExtractionError
too_large
too_large
Error message
This theme archive is too large to open in the browser editor. Extracted files must stay under ${getThemeArchiveSizeLabel(THEME_EDITOR_ARCHIVE_LIMITS.maxExtractedBytes)}. What it means
Thrown by trackExtractedBytes during extraction when the running total of extracted bytes exceeds THEME_EDITOR_ARCHIVE_LIMITS.maxExtractedBytes (32 MiB). This guards against zip-bomb-style or asset-heavy archives that would exhaust browser memory: each extracted file (text-encoded for editable files, raw bytes for binary) is added to a running total, and the limit is on the DECOMPRESSED size, not the archive size. Thrown as ThemeArchiveExtractionError with reason 'too_large'.
Source
Thrown at apps/admin/src/settings/app/components/settings/site/theme/theme-editor-utils.ts:234
throw new ThemeArchiveExtractionError('invalid_archive', invalidArchiveMessage);
}
};
const getNormalizedArchivePath = (path: string) => {
const normalizedPath = normaliseRelativePath(path);
if (!normalizedPath || normalizedPath !== path) {
throw new ThemeArchiveExtractionError('invalid_archive', invalidArchiveMessage);
}
return normalizedPath;
};
const trackExtractedBytes = (totalBytes: number, fileBytes: number) => {
const nextTotal = totalBytes + fileBytes;
if (nextTotal > THEME_EDITOR_ARCHIVE_LIMITS.maxExtractedBytes) {
throw new ThemeArchiveExtractionError(
'too_large',
`This theme archive is too large to open in the browser editor. Extracted files must stay under ${getThemeArchiveSizeLabel(THEME_EDITOR_ARCHIVE_LIMITS.maxExtractedBytes)}.`
);
}
return nextTotal;
};
export const extractThemeArchive = async (arrayBuffer: ArrayBuffer): Promise<ThemeEditorSnapshot> => {
const zip = await loadThemeArchive(arrayBuffer);
const entries = collectArchiveEntries(zip);
assertThemeArchiveLimits(entries);
const rootPrefix = detectCommonRoot(entries.map(([path]) => path));
const files: Record<string, ThemeEditorFile> = {};
const textEncoder = new TextEncoder();
let extractedBytes = 0;View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Reduce the extracted footprint: optimise/compress images, remove unused binary assets, and re-zip so the decompressed total stays under 32 MiB.
- Pre-check by summing uncompressed sizes locally (unzip -l shows uncompressed bytes per entry) before uploading.
- If the theme legitimately needs more, raise THEME_EDITOR_ARCHIVE_LIMITS.maxExtractedBytes, but reconsider whether the in-browser editor is the right tool — use server-side theme upload instead.
- Strip large media from the edit-time archive and add them back through Ghost's media management.
Example fix
// before — extraction throws ThemeArchiveExtractionError mid-flow
const snapshot = await extractThemeArchive(arrayBuffer);
// after — catch and branch on the typed reason
import {ThemeArchiveExtractionError} from './theme-editor-utils';
try {
const snapshot = await extractThemeArchive(arrayBuffer);
} catch (e) {
if (e instanceof ThemeArchiveExtractionError && e.reason === 'too_large') {
setUploadError(e.message); // 'This theme archive is too large ...'
return;
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// The limit is on DECOMPRESSED bytes, so you can't fully pre-validate from archive size,
// but you can reject obviously oversized archives early as a coarse guard.
const COARSE_LIMIT = 64 * 1024 * 1024; // be generous vs the 32 MiB extracted cap
if (arrayBuffer.byteLength > COARSE_LIMIT) {
setUploadError('Archive is too large for the browser editor.');
} Type guard
import {ThemeArchiveExtractionError} from './theme-editor-utils';
function isTooLarge(e: unknown): e is ThemeArchiveExtractionError {
return e instanceof ThemeArchiveExtractionError && e.reason === 'too_large';
} Try / catch
import {extractThemeArchive, ThemeArchiveExtractionError} from './theme-editor-utils';
try {
const snapshot = await extractThemeArchive(arrayBuffer);
} catch (e) {
if (e instanceof ThemeArchiveExtractionError && e.reason === 'too_large') {
setUploadError(e.message);
return;
}
throw e;
} Prevention
- Sum uncompressed entry sizes locally (unzip -l) before uploading to the browser editor.
- Optimise/compress large images, fonts, and media before zipping.
- For asset-heavy themes, prefer server-side theme upload.
- Branch on ThemeArchiveExtractionError.reason for specific messaging.
When it happens
Trigger: extractThemeArchive accumulates > 32 MiB across extracted entries. Triggers: a theme with large uncompressed images/fonts/videos, a highly compressible archive (zip bomb), or many binary assets whose summed byteLength crosses 32 MiB even if the .zip itself is small.
Common situations: Theme bundles full-resolution hero images, woff2 fonts, or video files; developer included raw (unoptimised) assets; malicious or pathological archive with high compression ratio; bundled sample media.
Related errors
- too_many_files
- invalid_archive
- Theme is not compatible or contains errors.
- A view with this name already exists
- The URL must be in a format like @username@instance.tld or h
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/30be764f488ba02a.
Report an issue: GitHub.