{"record":{"id":"1e0bc088e62ad153","repo":"Budibase/budibase","slug":"gemini-file-search-failed-set-gemini-api-key-on-y","errorCode":null,"errorMessage":"Gemini File Search failed. Set GEMINI_API_KEY on your local environment","messagePattern":"Gemini File Search failed\\. Set GEMINI_API_KEY on your local environment","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/ai/knowledgeBase/geminiFileStore.ts","lineNumber":75,"sourceCode":"interface RagSearchResponse {\n  data?: RagSearchResultItem[]\n}\n\ninterface GeminiFileStoreResponse {\n  ok: boolean\n  status: number\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504])\nconst RETRY_DELAYS_MS = [500, 1500, 3000]\n\nexport const isGeminiFileSearchConfigured = () =>\n  !!environment.GEMINI_API_KEY?.trim()\n\nexport const getGeminiApiKey = () => {\n  const key = environment.GEMINI_API_KEY?.trim()\n  if (!key) {\n    throw new HTTPError(\n      \"Gemini File Search failed. Set GEMINI_API_KEY on your local environment\",\n      400\n    )\n  }\n  return key\n}\n\nconst isRetryableResponse = (response: GeminiFileStoreResponse) => {\n  return !response.ok && RETRYABLE_STATUS_CODES.has(response.status)\n}\n\nconst isRetryableFetchError = (error: unknown) => {\n  return error instanceof Error && error.name === \"FetchError\"\n}\n\nconst requestWithRetries = async <TResponse extends GeminiFileStoreResponse>(\n  request: () => Promise<TResponse>\n): Promise<TResponse> => {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/ai/knowledgeBase/geminiFileStore.ts#L57-L93","documentation":"getGeminiApiKey reads environment.GEMINI_API_KEY and throws HTTPError 400 when it is missing or empty. Gemini File Search for knowledge bases requires this key to authenticate against Gemini via LiteLLM.","triggerScenarios":"Any Gemini file-store operation (createGeminiFileStore, deleteGeminiVectorStore, ingestGeminiFile, searchGeminiFileStore) invoked when GEMINI_API_KEY is unset, empty, or whitespace-only in the server environment.","commonSituations":"Local/self-hosted dev environment where GEMINI_API_KEY was never added to .env; key defined only in the builder/worker env but not the server process; server not restarted after adding the key; key accidentally set to blank after a deploy.","solutions":["Set GEMINI_API_KEY=<valid key> in the server's environment (.env) and restart the server","Verify with isGeminiFileSearchConfigured() before attempting Gemini knowledge base operations","Check the key is present in the same process that runs packages/server, not only worker or builder"],"exampleFix":"// before (.env)\n# GEMINI_API_KEY not set\n// after (.env)\nGEMINI_API_KEY=AIza...\n# then restart the server process","handlingStrategy":"validation","validationCode":"import { isGeminiFileSearchConfigured } from \"./geminiFileStore\"\nif (!isGeminiFileSearchConfigured()) {\n  throw new Error(\"GEMINI_API_KEY is not configured\")\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ingestGeminiFile({ ... })\n} catch (e) {\n  if (e instanceof HTTPError && e.status === 400 && /GEMINI_API_KEY/.test(e.message)) {\n    // surface a configuration hint to the operator\n  }\n}","preventionTips":["Set GEMINI_API_KEY in the server .env and restart the process","Gate Gemini KB features behind isGeminiFileSearchConfigured() in the UI/API","Include the env var in deployment checklists and health checks"],"tags":["configuration","environment-variable","gemini"],"backgroundTag":"missing-env-var","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}