Budibase/budibase · error · HTTPError
agentId is required
Error message
agentId is required
What it means
prepareChatConversationForSave builds the ChatConversation document to persist. It resolves agentId from the existing chat or the incoming request; if neither provides one, the conversation cannot be associated with an agent and a 400 HTTPError is thrown. The field is required for every saved chat conversation.
Source
Thrown at packages/server/src/sdk/workspace/ai/chatConversations/helpers.ts:36
}
export const prepareChatConversationForSave = ({
chatId,
userId,
title,
messages,
chat,
existingChat,
}: PrepareChatConversationForSaveParams): ChatConversation => {
const now = new Date().toISOString()
const createdAt = existingChat?.createdAt || chat.createdAt || now
const updatedAt = now
const rev = existingChat?._rev || chat._rev
const agentId = existingChat?.agentId || chat.agentId
const channel = chat.channel || existingChat?.channel
if (!agentId) {
throw new HTTPError("agentId is required", 400)
}
return {
_id: chatId,
...(rev && { _rev: rev }),
agentId,
userId,
title: title ?? chat.title,
messages: truncateToolPartsForSave(messages),
updatedAt,
...(createdAt && { createdAt }),
...(channel && { channel }),
}
}
export const extractUserText = (
message?: ChatConversation["messages"][number]
) => {View on GitHub (pinned to a81a902e9a)
Solutions
- Include agentId in the ChatConversationRequest payload when creating/updating conversations.
- Verify the existing conversation document has agentId before attempting updates.
- Catch the 400 HTTPError and reject/repair requests missing agentId at the API boundary.
Example fix
// before
await api.saveChatConversation({ chatId, messages }) // 400: agentId required
// after
await api.saveChatConversation({ chatId, agentId: agent._id, messages }) Defensive patterns
Strategy: validation
Validate before calling
const canSave = (chat: Partial<ChatConversationRequest>, existing?: ChatConversation | null) =>
!!(existing?.agentId || chat.agentId)
if (!canSave(chat, existingChat)) {
throw new HTTPError("agentId is required", 400)
} Type guard
const hasAgentId = (
chat: Partial<ChatConversationRequest>,
existingChat?: ChatConversation | null
): chat is Partial<ChatConversationRequest> & { agentId: string } =>
!!(existingChat?.agentId || chat.agentId) Try / catch
try {
const doc = prepareChatConversationForSave(params)
} catch (err) {
if (err instanceof HTTPError && err.status === 400 && err.message === "agentId is required") {
// reject the request / repair the payload with the resolved agentId
}
} Prevention
- Validate agentId presence in request-body schemas at the API layer.
- Always pass agentId explicitly when creating conversations; never rely on inheritance.
- Include agentId in chat client SDK request types as required.
When it happens
Trigger: Saving/creating a chat conversation where chat.agentId is missing and there is no existingChat to inherit it from - e.g. a client POSTing a conversation payload without agentId, or updating a conversation whose stored agentId was lost.
Common situations: Custom chat integrations omitting agentId in the request body; API version changes altering required fields; corrupted/existing conversations missing agentId being updated.
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/c381cfaf8c8f79bb.
Report an issue: GitHub.