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

  1. Remove role "tool" messages from the array before calling toPrompt.
  2. Convert tool results into assistant/user text summaries if the context matters.
  3. 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

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-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/635f0913fd4590ef. Report an issue: GitHub.