{"record":{"id":"3ff6027b4cfeace5","repo":"Budibase/budibase","slug":"failed-to-upload-icon-icon-src-uploaderror","errorCode":null,"errorMessage":"Failed to upload icon ${icon.src}: ${uploadError}","messagePattern":"Failed to upload icon (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/api/controllers/static/index.ts","lineNumber":435,"sourceCode":"        icon.type || (extension === \".png\" ? \"image/png\" : \"image/jpeg\")\n\n      try {\n        const result = await objectStore.upload({\n          bucket: ObjectStoreBuckets.APPS,\n          filename: key,\n          path: resolvedSrc,\n          type: mimeType,\n        })\n\n        if (result.Key) {\n          icons.push({\n            src: result.Key,\n            sizes: icon.sizes,\n            type: mimeType,\n          })\n        }\n      } catch (uploadError) {\n        throw new Error(`Failed to upload icon ${icon.src}: ${uploadError}`)\n      }\n    }\n\n    if (icons.length === 0) {\n      ctx.throw(400, \"No valid icons found in the zip file\")\n    }\n\n    ctx.body = { icons }\n  } catch (error) {\n    if (error && typeof error === \"object\" && \"status\" in error) {\n      throw error\n    }\n\n    const errorMessage =\n      error instanceof Error ? error.message : \"Unknown error\"\n    ctx.throw(500, `Error processing zip: ${errorMessage}`)\n  } finally {\n    await fsp.rm(tempDir, { recursive: true, force: true })","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/static/index.ts#L417-L453","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the wrapped root cause in the message and fix that underlying error first","Convert icons in the PWA zip to PNG/ICO and rebuild the zip","Verify MinIO/S3 is reachable and credentials are correct (docker ps, bucket config)","Re-export the PWA zip ensuring the manifest icon srcs point at real, non-empty files"],"exampleFix":"// manifest.json before\n\"icons\": [{ \"src\": \"icon.svg\", \"sizes\": \"any\", \"type\": \"image/svg+xml\" }]\n// after\n\"icons\": [{ \"src\": \"icon-512.png\", \"sizes\": \"512x512\", \"type\": \"image/png\" }]","handlingStrategy":"try-catch","validationCode":"// pre-validate PWA zip icons\nconst icons = manifest.icons || []\nfor (const icon of icons) {\n  if (!icon.src || !zip.file(icon.src)) throw new Error(`missing icon ${icon.src}`)\n  if (/\\.svg$/i.test(icon.src)) throw new Error(\"use PNG/ICO icons, SVG uploads are blocked\")\n}","typeGuard":null,"tryCatchPattern":"try {\n  const pwa = await api.processPWAZip(zip)\n} catch (e) {\n  if (/Failed to upload icon/.test(e.message)) {\n    const cause = e.message.split(\": \").slice(1).join(\": \")\n    // inspect cause: S3 connectivity vs active-content block vs corrupt icon\n  } else throw e\n}","preventionTips":["Ship PWA icons as PNG/ICO only","Verify MinIO/S3 health before PWA uploads","Ensure manifest icon srcs point at real non-empty files","Test PWA zips in a staging app first"],"tags":["pwa","upload","s3"],"backgroundTag":"asset-upload-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}