Budibase/budibase · error · BadRequestError

Invalid zip - uncompressed contents exceed the maximum size

Error message

Invalid zip - uncompressed contents exceed the maximum size

What it means

Thrown by validatePWAZipEntries when the cumulative uncompressed size of all zip entries exceeds MAX_PWA_ZIP_TOTAL_SIZE (50MB). It runs after each per-file check and bounds the total extracted footprint of the PWA in storage.

Source

Thrown at packages/server/src/api/controllers/static/index.ts:138

      return
    }

    fileCount++
    if (fileCount > MAX_PWA_ZIP_FILE_COUNT) {
      throw new BadRequestError(
        `Invalid zip - too many files (max ${MAX_PWA_ZIP_FILE_COUNT})`
      )
    }

    if (entry.uncompressedSize > MAX_PWA_ZIP_ENTRY_SIZE) {
      throw new BadRequestError(
        `Invalid zip - file "${entry.fileName}" exceeds the maximum size`
      )
    }

    totalUncompressedSize += entry.uncompressedSize
    if (totalUncompressedSize > MAX_PWA_ZIP_TOTAL_SIZE) {
      throw new BadRequestError(
        "Invalid zip - uncompressed contents exceed the maximum size"
      )
    }
  }
}

const listFilesRecursively = async (directory: string): Promise<string[]> => {
  const entries = await fsp.readdir(directory, { withFileTypes: true })
  const files = await Promise.all(
    entries.map(async entry => {
      const entryPath = join(directory, entry.name)
      if (entry.isDirectory()) {
        return await listFilesRecursively(entryPath)
      }

      if (entry.isFile()) {
        return [entryPath]
      }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Trim archive contents until total uncompressed size is under 50MB
  2. Optimize images (WebP/lossy compression) and drop unused locales
  3. Move large media to external hosting and reference by URL

Example fix

// before
60 uncompressed MB of PNGs in the zip
// after
converted to WebP: 40 uncompressed MB total
Defensive patterns

Strategy: validation

Validate before calling

function isPwaZipTotalSizeSafe(entries, maxTotal = 50 * 1024 * 1024) {
  return entries.reduce((sum, e) => sum + e.uncompressedSize, 0) <= maxTotal
}

Type guard

const isZipEntryList = (v: unknown): v is Array<{ fileName: string; uncompressedSize: number }> =>
  Array.isArray(v) && v.every(e => typeof e?.fileName === 'string' && typeof e?.uncompressedSize === 'number')

Try / catch

try {
  await uploadPwaZip(zip)
} catch (err) {
  if (err instanceof BadRequestError && err.message.includes('uncompressed contents exceed')) {
    // trim/optimize archive contents and retry
  } else throw err
}

Prevention

When it happens

Trigger: Uploading a PWA zip where the sum of all entries' uncompressedSize exceeds 50MB, even if each individual file is under 10MB.

Common situations: A media-heavy PWA with many images/videos, or a zip that decompresses far beyond its small compressed size (high compression ratio archive).

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/da7899b14781be77. Report an issue: GitHub.