Budibase/budibase · error · HTTPError

${error?.message} || Failed to process uploaded file

Error message

${error?.message} || Failed to process uploaded file

What it means

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.

Source

Thrown at packages/server/src/api/controllers/ai/files.ts:243

    const normalizedMessage = String(error?.message || "").toLowerCase()
    const isGeminiUpstreamUnavailable =
      error?.status === 503 ||
      error?.statusCode === 503 ||
      normalizedMessage.includes("upstream unavailable") ||
      normalizedMessage.includes("service unavailable")

    if (isGeminiUpstreamUnavailable) {
      console.error("[AI_UPSTREAM] Gemini unavailable", {
        event: GEMINI_UPSTREAM_EVENT,
        provider: "gemini",
        path: "knowledge_ingest",
        upstreamStatus: error?.status,
        agentId,
        errorMessage: error?.message,
      })
    }
    console.error("Failed to upload agent file", error)
    throw new HTTPError(
      error?.message || "Failed to process uploaded file",
      400
    )
  } finally {
    await unlinkSafe(filePath)
  }
}

export async function deleteAgentFile(
  ctx: UserCtx<
    void,
    { deleted: true },
    { agentId: string; operationId: string; fileId: string }
  >
) {
  const { agentId, operationId, fileId } = ctx.params
  await sdk.ai.rag.deleteFileForOperation(agentId, operationId, fileId)
  ctx.body = { deleted: true }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Read error.message in the response to identify the underlying upstream failure.
  2. If the message indicates upstream unavailability or status 503, retry with exponential backoff.
  3. Verify Gemini / knowledge-base environment configuration when failures are consistent.
  4. Check server logs for 'Failed to upload agent file' and '[AI_UPSTREAM] Gemini unavailable' entries.

Example fix

// before
await upload(form) // unhandled, opaque 400
// after
try {
  await upload(form)
} catch (err) {
  if (err.status === 503 || /unavailable/i.test(err.message)) await retryWithBackoff(upload, form)
  else throw err
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await api.uploadAgentFile(agentId, operationId, form)
} catch (err) {
  const msg = err?.message || "Failed to process uploaded file"
  if (err.status === 503 || /unavailable/i.test(msg)) {
    // retry with backoff; Gemini upstream unavailable
  } else {
    // surface msg to the user
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: Gemini API outage or missing Gemini configuration in the environment; knowledge base store not provisioned for the operation; transient network failures during ingestion.

Related errors


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