{"record":{"id":"5a286a25d497e443","repo":"Budibase/budibase","slug":"chatconversationid-in-body-does-not-match-path","errorCode":null,"errorMessage":"chatConversationId in body does not match path","messagePattern":"chatConversationId in body does not match path","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/ai/chatConversations.ts","lineNumber":359,"sourceCode":"}\n\nconst applyChatStreamPathParams = (\n  chat: ChatAgentRequest,\n  params: UserCtx<ChatAgentRequest, void>[\"params\"]\n) => {\n  const agentId = params?.agentId\n  if (agentId && chat.agentId && chat.agentId !== agentId) {\n    throw new HTTPError(\"agentId in body does not match path\", 400)\n  }\n\n  const chatConversationId = params?.chatConversationId\n  if (\n    chatConversationId &&\n    chatConversationId !== \"new\" &&\n    chat._id &&\n    chat._id !== chatConversationId\n  ) {\n    throw new HTTPError(\"chatConversationId in body does not match path\", 400)\n  }\n\n  if (agentId) {\n    chat.agentId = agentId\n  }\n  if (chatConversationId && chatConversationId !== \"new\") {\n    chat._id = chatConversationId\n  }\n}\n\nconst resolveChatStreamRequest = async (\n  ctx: UserCtx<ChatAgentRequest, void>\n): Promise<ResolvedChatStreamRequest> => {\n  const chat = ctx.request.body\n  const userId = getGlobalUserId(ctx)\n  applyChatStreamPathParams(chat, ctx.params)\n\n  const workspaceId = context.getWorkspaceId()","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/chatConversations.ts#L341-L377","documentation":"Analogous to the agentId check: if the path's chatConversationId is a concrete id (not 'new') and the body's chat._id refers to a different conversation, the request is rejected with HTTP 400 to prevent writing messages into the wrong conversation.","triggerScenarios":"POST to a chat stream path containing a conversation id while body._id is a different conversation id, e.g. resuming a stale body against a new conversation URL.","commonSituations":"Client switching conversations but keeping an old body; retries after a conversation was created/deleted so ids diverge; copy-pasted request payloads.","solutions":["Set body._id to the same conversation id as in the path","Use 'new' in the path when starting a conversation and let the server assign the id","Clear the cached body's _id before reusing it for another conversation"],"exampleFix":"// before\nPOST /api/ai/chat/agent_1/conv_AAA/stream\n{ \"_id\": \"conv_BBB\", ... }\n// after\nPOST /api/ai/chat/agent_1/conv_AAA/stream\n{ \"_id\": \"conv_AAA\", ... }","handlingStrategy":"validation","validationCode":"if (body._id && pathConversationId !== \"new\" && body._id !== pathConversationId) {\n  throw new Error(\"body._id must match the path chatConversationId\")\n}","typeGuard":null,"tryCatchPattern":"try {\n  await streamChat(agentId, conversationId, body)\n} catch (e) {\n  if (e.status === 400 && String(e.message).includes(\"chatConversationId in body does not match path\")) {\n    // reset body._id or start a new conversation with \"new\"\n  }\n}","preventionTips":["Reset conversation state when switching conversations in the UI","Use \"new\" for fresh conversations and adopt the server-assigned id","Never mutate a stale body's conversation id manually"],"tags":["validation","http-400","api-mismatch"],"backgroundTag":"path-body-parameter-mismatch","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}