{"record":{"id":"9b1741b11b844cee","repo":"Budibase/budibase","slug":"unsupported-bbai-model-model","errorCode":null,"errorMessage":"Unsupported BBAI model: ${model}","messagePattern":"Unsupported BBAI model: (.+?)","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/ai/budibaseai-v2.ts","lineNumber":80,"sourceCode":"  }\n}\n\nexport async function chatCompletionV2(ctx: Ctx<ChatCompletionRequestV2>) {\n  const { messages, model, stream } = ctx.request.body\n\n  if (!messages?.length) {\n    ctx.throw(400, \"Missing required field: messages\")\n  }\n\n  if (env.SELF_HOSTED && !env.isDev()) {\n    ctx.throw(500, \"Budibase AI endpoints are not available in self-host\")\n  }\n\n  if (!model) {\n    ctx.throw(400, \"Missing required field: model\")\n  }\n  if (!model?.startsWith(\"budibase/\")) {\n    throw new HTTPError(`Unsupported BBAI model: ${model}`, 400)\n  }\n\n  const bbaiKey = bbai.getBBAIKey()\n\n  await quotas.throwIfBudibaseAICreditsExceeded()\n\n  const requestBody = {\n    ...ctx.request.body,\n    metadata: {\n      ...ctx.request.body.metadata,\n      tags: getBBAITags(),\n    },\n  }\n\n  const upstreamResponse = await fetch(\n    `${environment.LITELLM_URL.replace(/\\/$/, \"\")}/chat/completions`,\n    {\n      method: \"POST\",","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/budibaseai-v2.ts#L62-L98","documentation":"Budibase AI v2 chat completions only accept model identifiers namespaced with the 'budibase/' prefix. If the request body's model field is set to anything else (OpenAI-style names, custom strings, empty-ish variants), the endpoint rejects it with HTTP 400 to prevent routing to unknown providers.","triggerScenarios":"POST to the BBAI v2 chat completion endpoint with body.model such as 'gpt-4o', 'claude-3', or a typo'd id that does not start with 'budibase/'.","commonSituations":"Clients configured for the generic OpenAI-compatible API reused against Budibase AI; model lists copied from other providers; older SDK versions pre-dating the budibase/ prefix convention.","solutions":["Prefix the model with 'budibase/', e.g. model: 'budibase/gpt-4o-mini'","Check the deployed Budibase version for the exact list of supported budibase/ model ids","If you need a non-budibase provider, call that provider's API directly instead of the BBAI endpoint"],"exampleFix":"// before\n{ \"model\": \"gpt-4o-mini\", \"messages\": [...] }\n// after\n{ \"model\": \"budibase/gpt-4o-mini\", \"messages\": [...] }","handlingStrategy":"validation","validationCode":"if (!model?.startsWith(\"budibase/\")) {\n  throw new Error(`Model must start with \"budibase/\", got: ${model}`)\n}","typeGuard":"const isBbaiModel = (m: unknown): m is `budibase/${string}` =>\n  typeof m === \"string\" && m.startsWith(\"budibase/\")","tryCatchPattern":"try {\n  await bbaiChat({ model, messages })\n} catch (e) {\n  if (e.status === 400 && String(e.message).includes(\"Unsupported BBAI model\")) {\n    // correct the model id and retry once\n  }\n}","preventionTips":["Keep a single BBAI_MODEL constant with the budibase/ prefix","Validate model names against a supported list before sending","Never reuse OpenAI/Anthropic model ids against the BBAI endpoint"],"tags":["validation","http-400","ai"],"backgroundTag":"invalid-model-identifier","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}