continuedev/continue · error · Error
Unexpected message received from Ollama with role = tool
Error message
Unexpected message received from Ollama with role = tool
What it means
Thrown by convertChatMessage in Ollama._streamChat when a streamed message arrives with role === "tool". The /api/chat response stream from the client's perspective should only contain assistant/user-shaped messages; a tool-role message means the conversation history sent to Ollama contains tool results formatted in a way Ollama echoes back instead of consuming.
Source
Thrown at core/llm/llms/Ollama.ts:581
// When Streaming you can't have both thinking and content
return [thinkingMessage];
}
}
if (content) {
const chatMessage: ChatMessage = {
role: "assistant",
content: content,
};
return [chatMessage];
}
return [];
}
const { role, content, thinking, tool_calls: toolCalls } = res.message;
if (role === "tool") {
throw new Error(
"Unexpected message received from Ollama with role = tool",
);
}
if (role === "assistant") {
const thinkingMessage: ThinkingChatMessage | null = thinking
? { role: "thinking", content: thinking }
: null;
if (thinkingMessage && !content && !toolCalls?.length) {
// When Streaming you can't have both thinking and content
return [thinkingMessage];
}
// Either not thinking, or not streaming
const chatMessage: ChatMessage = { role: "assistant", content };
if (toolCalls?.length) {
// Continue handles the response as a tool call delta butView on GitHub (pinned to 5522c6f44c)
Solutions
- Update Ollama to the latest version (tool-call message schema changed across releases)
- Disable tools/agent mode for that model if the Ollama build doesn't support them
- Clear the chat session so stale tool messages aren't replayed in history
Defensive patterns
Strategy: validation
Validate before calling
const messages = history.filter(m => m.role !== 'tool' || supportsOllamaTools); if (messages.some(m => m.role === 'tool') && !supportsOllamaTools) stripToolMessages();
Type guard
function isOllamaToolRoleError(e: unknown): boolean { return e instanceof Error && e.message.includes('role = tool'); } Try / catch
try { for await (const m of llm.streamChat(messages, signal)) handle(m); }
catch (e) { if (isOllamaToolRoleError(e)) restartSessionWithoutTools(); else throw e; } Prevention
- Pin a recent Ollama version when using tool calling
- Start a fresh session after toggling tools/agent mode
When it happens
Trigger: Using Ollama tool-calling in Continue and the message history contains a tool result message that Ollama's API passes through with role 'tool' instead of mapping it, or an Ollama version whose tool-message schema differs from what the client sends.
Common situations: Version mismatch between the Ollama server and the client's tool-call message format; older Ollama builds that don't support the tools API properly.
Related errors
- res.error
- Failed to fetch Ollama library: ${response.status}
- Error fetching tags: ${e.message}
- HTTP ${e.response.status} ${e.response.statusText} from ${e.
- Unable to connect to local Ollama instance. Ollama may not b
AI-assisted analysis of continuedev/continue@5522c6f44c (2026-08-27).
Data as JSON: /api/errors/16a4352c8c01108c.
Report an issue: GitHub.