{"record":{"id":"24b885f50f9c9916","repo":"Budibase/budibase","slug":"invalid-zip-file-entry-filename-exceeds-the","errorCode":null,"errorMessage":"Invalid zip - file \"${entry.fileName}\" exceeds the maximum size","messagePattern":"Invalid zip - file \"(.+?)\" exceeds the maximum size","errorType":"http","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/static/index.ts","lineNumber":131,"sourceCode":"      throw new BadRequestError(\n        `Invalid zip - directory depth exceeds ${MAX_PWA_ZIP_DEPTH}`\n      )\n    }\n\n    // Directory entries carry no content, only enforce the depth limit on them.\n    if (entry.fileName.endsWith(\"/\")) {\n      return\n    }\n\n    fileCount++\n    if (fileCount > MAX_PWA_ZIP_FILE_COUNT) {\n      throw new BadRequestError(\n        `Invalid zip - too many files (max ${MAX_PWA_ZIP_FILE_COUNT})`\n      )\n    }\n\n    if (entry.uncompressedSize > MAX_PWA_ZIP_ENTRY_SIZE) {\n      throw new BadRequestError(\n        `Invalid zip - file \"${entry.fileName}\" exceeds the maximum size`\n      )\n    }\n\n    totalUncompressedSize += entry.uncompressedSize\n    if (totalUncompressedSize > MAX_PWA_ZIP_TOTAL_SIZE) {\n      throw new BadRequestError(\n        \"Invalid zip - uncompressed contents exceed the maximum size\"\n      )\n    }\n  }\n}\n\nconst listFilesRecursively = async (directory: string): Promise<string[]> => {\n  const entries = await fsp.readdir(directory, { withFileTypes: true })\n  const files = await Promise.all(\n    entries.map(async entry => {\n      const entryPath = join(directory, entry.name)","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/static/index.ts#L113-L149","documentation":"Thrown by validatePWAZipEntries when a single zip entry's uncompressedSize exceeds MAX_PWA_ZIP_ENTRY_SIZE (10MB). This prevents individual entries from consuming excessive disk and memory when the PWA is extracted and served.","triggerScenarios":"Uploading a PWA zip where any one file, e.g. a large image or bundle, decompresses to more than 10MB.","commonSituations":"Including an oversized hero image, a multi-megabyte font set, or an unminified JS bundle inside the PWA archive.","solutions":["Compress or resize the offending file below 10MB uncompressed","Minify JS/CSS and strip source maps from the archive","Remove large assets not required by the manifest"],"exampleFix":"// before\nbundle.js (unminified, 14MB uncompressed)\n// after\nbundle.min.js (2MB uncompressed)","handlingStrategy":"validation","validationCode":"function isPwaZipEntrySizeSafe(entries, maxPerFile = 10 * 1024 * 1024) {\n  return entries.every(e => e.uncompressedSize <= maxPerFile)\n}","typeGuard":"const hasUncompressedSize = (e: unknown): e is { uncompressedSize: number } =>\n  typeof e === 'object' && e !== null && typeof (e as any).uncompressedSize === 'number'","tryCatchPattern":"try {\n  await uploadPwaZip(zip)\n} catch (err) {\n  if (err instanceof BadRequestError && err.message.includes('exceeds the maximum size')) {\n    // minify/compress the named file and retry\n  } else throw err\n}","preventionTips":["Check each file's uncompressed size before zipping; keep under 10MB","Minify JS/CSS and strip source maps from PWA archives","Compress large images and subset fonts"],"tags":["validation","pwa","upload","zip","file-size"],"backgroundTag":"zip-validation-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}