{"record":{"id":"efe725ab8e10813c","repo":"Budibase/budibase","slug":"error-message-failed-to-process-uploaded-fi","errorCode":null,"errorMessage":"${error?.message} || Failed to process uploaded file","messagePattern":"(.+?) \\|\\| Failed to process uploaded file","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/ai/files.ts","lineNumber":243,"sourceCode":"    const normalizedMessage = String(error?.message || \"\").toLowerCase()\n    const isGeminiUpstreamUnavailable =\n      error?.status === 503 ||\n      error?.statusCode === 503 ||\n      normalizedMessage.includes(\"upstream unavailable\") ||\n      normalizedMessage.includes(\"service unavailable\")\n\n    if (isGeminiUpstreamUnavailable) {\n      console.error(\"[AI_UPSTREAM] Gemini unavailable\", {\n        event: GEMINI_UPSTREAM_EVENT,\n        provider: \"gemini\",\n        path: \"knowledge_ingest\",\n        upstreamStatus: error?.status,\n        agentId,\n        errorMessage: error?.message,\n      })\n    }\n    console.error(\"Failed to upload agent file\", error)\n    throw new HTTPError(\n      error?.message || \"Failed to process uploaded file\",\n      400\n    )\n  } finally {\n    await unlinkSafe(filePath)\n  }\n}\n\nexport async function deleteAgentFile(\n  ctx: UserCtx<\n    void,\n    { deleted: true },\n    { agentId: string; operationId: string; fileId: string }\n  >\n) {\n  const { agentId, operationId, fileId } = ctx.params\n  await sdk.ai.rag.deleteFileForOperation(agentId, operationId, fileId)\n  ctx.body = { deleted: true }","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/files.ts#L225-L261","documentation":"Generic catch-all in uploadAgentFile: any error thrown by sdk.ai.rag.uploadFileForOperation (Gemini file-search upload, DB update, quota) is logged and rethrown as HTTP 400 with the upstream message, or this fallback message when the error has no message.","triggerScenarios":"Gemini/knowledge-base upstream unavailable (503, logged as [AI_UPSTREAM] Gemini unavailable); invalid agentId/operationId for the RAG operation; file too large or rejected by the ingestion API; database update failures after upload.","commonSituations":"Gemini API outage or missing Gemini configuration in the environment; knowledge base store not provisioned for the operation; transient network failures during ingestion.","solutions":["Read error.message in the response to identify the underlying upstream failure.","If the message indicates upstream unavailability or status 503, retry with exponential backoff.","Verify Gemini / knowledge-base environment configuration when failures are consistent.","Check server logs for 'Failed to upload agent file' and '[AI_UPSTREAM] Gemini unavailable' entries."],"exampleFix":"// before\nawait upload(form) // unhandled, opaque 400\n// after\ntry {\n  await upload(form)\n} catch (err) {\n  if (err.status === 503 || /unavailable/i.test(err.message)) await retryWithBackoff(upload, form)\n  else throw err\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await api.uploadAgentFile(agentId, operationId, form)\n} catch (err) {\n  const msg = err?.message || \"Failed to process uploaded file\"\n  if (err.status === 503 || /unavailable/i.test(msg)) {\n    // retry with backoff; Gemini upstream unavailable\n  } else {\n    // surface msg to the user\n  }\n}","preventionTips":["Treat 400s from this endpoint as upstream-ingestion failures and surface error.message.","Retry on 503 / 'upstream unavailable' messages with exponential backoff.","Verify Gemini/knowledge-base configuration when uploads fail consistently.","Watch server logs for '[AI_UPSTREAM] Gemini unavailable' to distinguish upstream vs client issues."],"tags":["http-400","upstream","gemini","knowledge-base"],"backgroundTag":"upstream-service-unavailable","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}