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

  1. Set agentId on the chat request body to the id of an existing AI agent before calling the stream endpoint
  2. Fetch the agent list (sdk.ai.agents) to obtain a valid agentId and pass it through to the client
  3. If resuming an existing conversation, load the conversation document and reuse its agentId
  4. 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

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


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/7f425dae4a9f4d52. Report an issue: GitHub.