Budibase/budibase · error · HTTPError

${text || fallbackMessage}

Error message

${text || fallbackMessage}

What it means

handleNotOkResponse is the shared response checker for all Gemini File Search HTTP calls. When the LiteLLM proxy responds with a non-ok status not in allowedStatuses, it throws HTTPError carrying the raw response body text (or the caller's fallbackMessage) and the upstream status code. It is used by createGeminiFileStore, deleteGeminiVectorStore, ingestGeminiFile, searchGeminiFileStore and deleteGeminiFileFromStore.

Source

Thrown at packages/server/src/sdk/workspace/ai/knowledgeBase/geminiFileStore.ts:132

    attempt++
  }
}

const handleNotOkResponse = async ({
  response,
  fallbackMessage,
  allowedStatuses = [],
}: {
  response: { ok: boolean; status: number; text: () => Promise<string> }
  fallbackMessage: string
  allowedStatuses?: number[]
}): Promise<void> => {
  if (response.ok || allowedStatuses.includes(response.status)) {
    return
  }

  const text = await response.text()
  throw new HTTPError(text || fallbackMessage, response.status)
}

const getCommonAuthHeaders = async () => {
  const { secretKey } = await getKeySettings()
  const authKey = environment.LITELLM_MASTER_KEY || secretKey
  return {
    "Content-Type": "application/json",
    Authorization: `Bearer ${authKey}`,
  }
}

export async function createGeminiFileStore(name: string): Promise<string> {
  const geminiApiKey = getGeminiApiKey()
  const response = await fetch(`${environment.LITELLM_URL}/v1/vector_stores`, {
    method: "POST",
    headers: await getCommonAuthHeaders(),
    body: JSON.stringify({
      name,

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Read the thrown message — it is the upstream response body — to identify the real cause
  2. Verify LITELLM_URL and LITELLM_MASTER_KEY / LiteLLM key settings are correct and the proxy is healthy
  3. Check the Gemini API key validity and quota; retry 429/5xx (the code already retries these for some calls)
  4. If the store was deleted upstream, use 'Reset store' to recreate the vector store

Example fix

// before
const res = await fetch(`${LITELLM_URL}/v1/vector_stores`, { headers }) // 401 body thrown raw
// after
try {
  await createGeminiFileStore(name)
} catch (e) {
  if (e instanceof HTTPError && e.status === 401) {
    // fix LITELLM_MASTER_KEY / key settings
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

const health = await fetch(`${process.env.LITELLM_URL}/health`)
if (!health.ok) throw new Error("LiteLLM proxy unavailable")

Try / catch

try {
  await createGeminiFileStore(name)
} catch (e) {
  if (e instanceof HTTPError) {
    console.error(`Gemini call failed ${e.status}: ${e.message}`) // body is upstream text
    // handle 401 (auth key), 429/5xx (retry), 403/404 (reset store)
  }
}

Prevention

When it happens

Trigger: Any LiteLLM/Gemini request returns an error status (e.g. 401 bad LiteLLM auth key, 403/404 store access issues, 429 rate limit after retries, 5xx) — the thrown message is the upstream response body.

Common situations: LITELLM_MASTER_KEY or key settings secretKey mismatched with the LiteLLM proxy; LITELLM_URL pointing at a wrong/unreachable proxy returning an HTML error page; Gemini upstream rejecting the API key or quota exhausted; vector store deleted upstream while Budibase still references it.

Related errors


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