Budibase/budibase · error · Error
AI tool messages are not supported
Error message
AI tool messages are not supported
What it means
During toPrompt conversion, any message with role "tool" is rejected with this Error because the prompt builder only supports system/user/assistant text messages. Tool-call result messages have no representation in the generated prompt, so the library fails fast rather than silently dropping context.
Source
Thrown at packages/server/src/sdk/workspace/ai/llm/messages.ts:15
import type { Message } from "@budibase/types"
import type { ModelMessage } from "ai"
export function toPrompt(messages: Message[]): {
instructions?: string
messages: ModelMessage[]
} {
const instructions: string[] = []
const modelMessages: ModelMessage[] = []
for (const message of messages) {
if (typeof message.content !== "string") {
throw new Error("AI message content must be a string")
}
if (message.role === "tool") {
throw new Error("AI tool messages are not supported")
}
if (message.role === "system") {
instructions.push(message.content)
} else {
modelMessages.push({
role: message.role,
content: message.content,
} as ModelMessage)
}
}
return {
instructions: instructions.join("\n\n") || undefined,
messages: modelMessages,
}
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Remove role "tool" messages from the array before calling toPrompt.
- Convert tool results into assistant/user text summaries if the context matters.
- Use an API path that supports tool messages if tool context is required.
Example fix
// before toPrompt(messages) // after toPrompt(messages.filter(m => m.role !== "tool"))
Defensive patterns
Strategy: validation
Validate before calling
if (messages.some(m => m.role === "tool")) {
throw new Error("History contains tool messages; strip them before calling toPrompt")
} Type guard
const hasToolMessages = (msgs: ModelMessage[]): boolean => msgs.some(m => m.role === "tool")
Try / catch
try {
return toPrompt(messages)
} catch (e) {
if (e.message === "AI tool messages are not supported") {
return toPrompt(messages.filter(m => m.role !== "tool"))
}
throw e
} Prevention
- Filter role "tool" messages out of history before prompt construction
- Summarize tool results into assistant/user text if context is needed
- Keep tool transcripts in a separate store from promptable history
- Test multi-step agent flows for tool-message leakage into toPrompt
When it happens
Trigger: Calling toPrompt with a conversation history that includes role "tool" messages — typically the output of a prior tool-calling LLM run that was replayed into the prompt builder.
Common situations: Replaying persisted chat history that contains tool-call turns; chaining multi-step agent runs where tool results are kept in the message list; passing Vercel AI SDK response messages directly to toPrompt.
Related errors
- AI message content must be a string
- Streaming not supported in this browser
- Error generating tables
- No result received from table generation stream
- LLM not available
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/635f0913fd4590ef.
Report an issue: GitHub.