Budibase/budibase · error · Error

Failed to upload icon ${icon.src}: ${uploadError}

Error message

Failed to upload icon ${icon.src}: ${uploadError}

What it means

During PWA zip processing, processPWAZip extracts icon entries from the uploaded zip and uploads each to object storage; if any single icon upload fails, the original error is wrapped in 'Failed to upload icon <src>: <error>'. The root cause (S3 error, active-content rejection, network failure) is preserved in the message.

Source

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

        icon.type || (extension === ".png" ? "image/png" : "image/jpeg")

      try {
        const result = await objectStore.upload({
          bucket: ObjectStoreBuckets.APPS,
          filename: key,
          path: resolvedSrc,
          type: mimeType,
        })

        if (result.Key) {
          icons.push({
            src: result.Key,
            sizes: icon.sizes,
            type: mimeType,
          })
        }
      } catch (uploadError) {
        throw new Error(`Failed to upload icon ${icon.src}: ${uploadError}`)
      }
    }

    if (icons.length === 0) {
      ctx.throw(400, "No valid icons found in the zip file")
    }

    ctx.body = { icons }
  } catch (error) {
    if (error && typeof error === "object" && "status" in error) {
      throw error
    }

    const errorMessage =
      error instanceof Error ? error.message : "Unknown error"
    ctx.throw(500, `Error processing zip: ${errorMessage}`)
  } finally {
    await fsp.rm(tempDir, { recursive: true, force: true })

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Read the wrapped root cause in the message and fix that underlying error first
  2. Convert icons in the PWA zip to PNG/ICO and rebuild the zip
  3. Verify MinIO/S3 is reachable and credentials are correct (docker ps, bucket config)
  4. Re-export the PWA zip ensuring the manifest icon srcs point at real, non-empty files

Example fix

// manifest.json before
"icons": [{ "src": "icon.svg", "sizes": "any", "type": "image/svg+xml" }]
// after
"icons": [{ "src": "icon-512.png", "sizes": "512x512", "type": "image/png" }]
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate PWA zip icons
const icons = manifest.icons || []
for (const icon of icons) {
  if (!icon.src || !zip.file(icon.src)) throw new Error(`missing icon ${icon.src}`)
  if (/\.svg$/i.test(icon.src)) throw new Error("use PNG/ICO icons, SVG uploads are blocked")
}

Try / catch

try {
  const pwa = await api.processPWAZip(zip)
} catch (e) {
  if (/Failed to upload icon/.test(e.message)) {
    const cause = e.message.split(": ").slice(1).join(": ")
    // inspect cause: S3 connectivity vs active-content block vs corrupt icon
  } else throw e
}

Prevention

When it happens

Trigger: Uploading a PWA zip whose manifest icons include a file that fails uploadToObjectStorage — e.g. an SVG icon caught by active-content checks, a corrupted/empty icon entry, or an S3/MinIO connectivity failure mid-processing.

Common situations: PWA packages generated with SVG icons (blocked by active-content filter); MinIO/S3 credentials or bucket misconfiguration in self-hosted environments; zip with broken icon paths referenced in manifest.

Related errors


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