{"record":{"id":"7f425dae4a9f4d52","repo":"Budibase/budibase","slug":"agentid-is-required","errorCode":null,"errorMessage":"agentId is required","messagePattern":"agentId is required","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/ai/chatConversations.ts","lineNumber":412,"sourceCode":"  if (!isDevWorkspaceID(workspaceId)) {\n    throw new HTTPError(\"Preview mode requires a development workspace\", 400)\n  }\n\n  let user = ctx.user\n  if (chat.previewRoleId) {\n    const previewRole = await roles.getRole(chat.previewRoleId)\n    if (!previewRole?._id) {\n      throw new HTTPError(\"Preview role not found\", 400)\n    }\n    user = {\n      ...ctx.user,\n      roleId: previewRole._id,\n    }\n  }\n\n  const agentId = chat.agentId\n  if (!agentId) {\n    throw new HTTPError(\"agentId is required\", 400)\n  }\n\n  return {\n    agentId,\n    chat,\n    userId,\n    user,\n  }\n}\n\nexport type WebhookAssistantStream = AsyncIterable<string>\n\nconst getAssistantMessageText = (assistantMessage?: UIMessage) =>\n  assistantMessage?.parts\n    ?.flatMap(part => (part.type === \"text\" ? [part.text] : []))\n    .join(\"\") || \"\"\n\nconst createAssistantTextStream = async function* (","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/chatConversations.ts#L394-L430","documentation":"resolveChatStreamRequest requires every chat stream request to carry an agentId, since the stream must be routed to a specific AI agent. If chat.agentId is missing (falsy) the controller rejects the request early with HTTP 400 before doing any work. This is a request-shape validation error, not a transient failure.","triggerScenarios":"Calling the chat stream API (POST to the chat conversations stream endpoint) with a chat body that omits agentId, or where agentId is null/empty string — e.g. a client resuming a conversation built without an agent, or a payload serialized from an object that never set agentId.","commonSituations":"Frontend clients constructing the chat payload manually and forgetting agentId; older clients/versions predating agentId being made mandatory; copying request examples that predate the agent model; programmatically built payloads where agentId comes from an unset variable.","solutions":["Set agentId on the chat request body to the id of an existing AI agent before calling the stream endpoint","Fetch the agent list (sdk.ai.agents) to obtain a valid agentId and pass it through to the client","If resuming an existing conversation, load the conversation document and reuse its agentId","Update client SDK/frontend code to a version that always includes agentId"],"exampleFix":"// before\nawait api.post(`/api/ai/chat/conversations/stream`, { chatId })\n// after\nawait api.post(`/api/ai/chat/conversations/stream`, { chatId, agentId: agent._id })","handlingStrategy":"validation","validationCode":"if (!chat.agentId) throw new Error(\"chat.agentId must be set before calling the chat stream API\")\nawait api.post(`/api/ai/chat/conversations/stream`, { ...chat, agentId: chat.agentId })","typeGuard":"function hasAgentId(chat: ChatConversationRequest): chat is ChatConversationRequest & { agentId: string } {\n  return typeof chat.agentId === \"string\" && chat.agentId.length > 0\n}","tryCatchPattern":"try {\n  await streamChat(chat)\n} catch (e) {\n  if (e instanceof HTTPError && e.status === 400 && e.message === \"agentId is required\") {\n    // reload conversation / prompt user to pick an agent\n  }\n  throw e\n}","preventionTips":["Always populate agentId when creating or resuming a chat conversation","Centralize chat request construction in one helper that asserts agentId","Type the request so agentId is required, not optional","Add a client-side check before network calls"],"tags":["validation","http-400","ai-agent"],"backgroundTag":"missing-required-field","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}