Budibase/budibase · error · HTTPError
Workspace ID is required to configure LiteLLM
Error message
Workspace ID is required to configure LiteLLM
What it means
getKeySettings lazily provisions the workspace's LiteLLM virtual key. It derives the lock/resource scope from context.getProdWorkspaceId(); when there is no prod workspace ID in the execution context (e.g. running at the global/platform level or inside a bare tenant DB), it cannot scope the key and throws HTTP 400 instead of creating a malformed key.
Source
Thrown at packages/server/src/sdk/workspace/ai/configs/litellm.ts:390
if (model.configType !== AIConfigType.COMPLETIONS) {
throw new HTTPError(`Unsupported AI config type: ${model.configType}`, 400)
}
return validateCompletionsModel(model)
}
export async function getKeySettings(): Promise<{
keyId: string
secretKey: string
teamId: string
}> {
const db = context.getWorkspaceDB()
const keyDocId = docIds.getLiteLLMKeyID()
let keyConfig = await db.tryGet<LiteLLMKeyConfig>(keyDocId)
if (!keyConfig || !keyConfig.teamId) {
const workspaceId = context.getProdWorkspaceId()
if (!workspaceId) {
throw new HTTPError("Workspace ID is required to configure LiteLLM", 400)
}
const { result } = await locks.doWithLock(
{
name: LockName.LITELLM_KEY,
type: LockType.AUTO_EXTEND,
resource: workspaceId,
},
async () => {
let existingKeyConfig = await db.tryGet<LiteLLMKeyConfig>(keyDocId)
const shouldCreateTenantTeam = !existingKeyConfig?.teamId
if (existingKeyConfig && !shouldCreateTenantTeam) {
return existingKeyConfig
}
const team = await getOrCreateTenantTeam()
if (existingKeyConfig) {View on GitHub (pinned to a81a902e9a)
Solutions
- Ensure the code runs inside a workspace context (context.withWorkspace / the request carries the app/workspace ID) before calling getKeySettings.
- Pass an explicit workspace ID to the surrounding operation so context.getProdWorkspaceId() resolves.
- For tests/scripts, wrap the call in the test helper that seeds prod workspace context.
Example fix
// before
await getKeySettings() // no workspace context
// after
await context.doInWorkspace(appId, async () => {
await getKeySettings()
}) Defensive patterns
Strategy: validation
Validate before calling
import { context } from "@budibase/backend-core"
const wsId = context.getProdWorkspaceId()
if (!wsId) throw new Error("Call getKeySettings only inside a prod workspace context") Try / catch
try {
await getKeySettings()
} catch (e) {
if (e.status === 400 && e.message.includes("Workspace ID is required")) {
// re-run wrapped in workspace context
return context.doInWorkspace(appId, getKeySettings)
}
throw e
} Prevention
- Only invoke LiteLLM key helpers from request/job code that runs within a workspace context.
- Assert workspace context exists at the top of scripts and tests.
- Route key provisioning through app-scoped endpoints rather than global admin code.
When it happens
Trigger: Calling getKeySettings (or code paths that call it: create/update of AI configs) while the request context has no production workspace — e.g. no workspace header/doc context, running against the global DB, or a job executing outside any app/workspace context.
Common situations: Background scripts or tests that call LiteLLM helpers without establishing workspace context (ctx/workflow context not set); AI config CRUD invoked from tenant-level admin endpoints.
Related errors
- Workspace context is required
- Preview mode requires a development workspace
- Invalid bookmark query
- Invalid limit query
- Limit query must be between 1 and 100
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/fc1735ecb7140724.
Report an issue: GitHub.