Budibase/budibase · error · HTTPError
agentId is required
Error message
agentId is required
What it means
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.
Source
Thrown at packages/server/src/api/controllers/ai/chatConversations.ts:412
if (!isDevWorkspaceID(workspaceId)) {
throw new HTTPError("Preview mode requires a development workspace", 400)
}
let user = ctx.user
if (chat.previewRoleId) {
const previewRole = await roles.getRole(chat.previewRoleId)
if (!previewRole?._id) {
throw new HTTPError("Preview role not found", 400)
}
user = {
...ctx.user,
roleId: previewRole._id,
}
}
const agentId = chat.agentId
if (!agentId) {
throw new HTTPError("agentId is required", 400)
}
return {
agentId,
chat,
userId,
user,
}
}
export type WebhookAssistantStream = AsyncIterable<string>
const getAssistantMessageText = (assistantMessage?: UIMessage) =>
assistantMessage?.parts
?.flatMap(part => (part.type === "text" ? [part.text] : []))
.join("") || ""
const createAssistantTextStream = async function* (View on GitHub (pinned to a81a902e9a)
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
Example fix
// before
await api.post(`/api/ai/chat/conversations/stream`, { chatId })
// after
await api.post(`/api/ai/chat/conversations/stream`, { chatId, agentId: agent._id }) Defensive patterns
Strategy: validation
Validate before calling
if (!chat.agentId) throw new Error("chat.agentId must be set before calling the chat stream API")
await api.post(`/api/ai/chat/conversations/stream`, { ...chat, agentId: chat.agentId }) Type guard
function hasAgentId(chat: ChatConversationRequest): chat is ChatConversationRequest & { agentId: string } {
return typeof chat.agentId === "string" && chat.agentId.length > 0
} Try / catch
try {
await streamChat(chat)
} catch (e) {
if (e instanceof HTTPError && e.status === 400 && e.message === "agentId is required") {
// reload conversation / prompt user to pick an agent
}
throw e
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Invalid bookmark query
- Invalid limit query
- Limit query must be between 1 and 100
- Invalid ${queryName} query
- Invalid environment query
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/7f425dae4a9f4d52.
Report an issue: GitHub.