{"record":{"id":"16a4352c8c01108c","repo":"continuedev/continue","slug":"unexpected-message-received-from-ollama-with-role","errorCode":null,"errorMessage":"Unexpected message received from Ollama with role = tool","messagePattern":"Unexpected message received from Ollama with role = tool","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/llm/llms/Ollama.ts","lineNumber":581,"sourceCode":"            // When Streaming you can't have both thinking and content\n            return [thinkingMessage];\n          }\n        }\n\n        if (content) {\n          const chatMessage: ChatMessage = {\n            role: \"assistant\",\n            content: content,\n          };\n          return [chatMessage];\n        }\n        return [];\n      }\n\n      const { role, content, thinking, tool_calls: toolCalls } = res.message;\n\n      if (role === \"tool\") {\n        throw new Error(\n          \"Unexpected message received from Ollama with role = tool\",\n        );\n      }\n\n      if (role === \"assistant\") {\n        const thinkingMessage: ThinkingChatMessage | null = thinking\n          ? { role: \"thinking\", content: thinking }\n          : null;\n\n        if (thinkingMessage && !content && !toolCalls?.length) {\n          // When Streaming you can't have both thinking and content\n          return [thinkingMessage];\n        }\n        // Either not thinking, or not streaming\n        const chatMessage: ChatMessage = { role: \"assistant\", content };\n\n        if (toolCalls?.length) {\n          // Continue handles the response as a tool call delta but","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/core/llm/llms/Ollama.ts#L563-L599","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const messages = history.filter(m => m.role !== 'tool' || supportsOllamaTools);\nif (messages.some(m => m.role === 'tool') && !supportsOllamaTools) stripToolMessages();","typeGuard":"function isOllamaToolRoleError(e: unknown): boolean { return e instanceof Error && e.message.includes('role = tool'); }","tryCatchPattern":"try { for await (const m of llm.streamChat(messages, signal)) handle(m); }\ncatch (e) { if (isOllamaToolRoleError(e)) restartSessionWithoutTools(); else throw e; }","preventionTips":["Pin a recent Ollama version when using tool calling","Start a fresh session after toggling tools/agent mode"],"tags":["ollama","tool-calling","schema-mismatch","chat"],"backgroundTag":"llm-provider-stream-error","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}