zed-industries/zed · error
Only tool result should be extracted
Error message
Only tool result should be extracted
What it means
When converting Zed's internal message representation into an Ollama chat request, the code maps message content parts to Ollama message types. Tool-result content parts are expected to be filtered/extracted earlier in the conversion; if any other content-part variant reaches this match arm, the code declares it a logic error and panics with 'Only tool result should be extracted'.
Solutions
- Update the Ollama provider's `to_ollama_request` to map the new content-part variant to the appropriate Ollama message type.
- Filter non-tool-result parts before this match so only tool results are extracted, mirroring how other providers do it.
- Log and skip unrecognized parts instead of panicking, so chats with mixed content degrade gracefully.
Example fix
// before
_ => unreachable!("Only tool result should be extracted"),
// after
other => {
log::warn!("skipping unsupported content part in ollama request: {other:?}");
continue;
} Defensive patterns
Strategy: fallback
Validate before calling
// validate message contents before building the request
let unsupported: Vec<_> = msg.content.iter().filter(|p| !matches!(p, MessageContent::ToolResult(_))).collect();
if !unsupported.is_empty() { /* log and skip or return an error */ } Type guard
fn is_tool_result(part: &MessageContent) -> bool {
matches!(part, MessageContent::ToolResult(_))
} Try / catch
// the panic is unreachable!(); wrap request building at the boundary
let request = std::panic::catch_unwind(|| to_ollama_request(&messages)).map_err(|_| anyhow!("ollama request conversion failed"))?; Prevention
- Normalize/extract tool results from messages before provider-specific conversion.
- When adding MessageContent variants, update every provider's to_*_request.
- Prefer warn-and-skip over unreachable for unrecognized content parts.
When it happens
Trigger: Streaming a completion whose request message contains a content part that is neither handled upstream nor a tool result — e.g. a `ToolUse` or image/text variant reaching the extraction branch in `to_ollama_request` because the assistant/user message wasn't normalized first.
Common situations: New `MessageContent` variants added to the language model protocol without updating the Ollama provider conversion; requests built from conversation history containing unmatched tool-call/tool-result pairs.
Related errors
- internal error: entered unreachable code
- row grapheme cursor
- actions.json not found at
- already subscribed to entity
- anchor's path was never added to multibuffer
AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19).
Data as JSON: /api/errors/c8caadb9a489bc49.
Report an issue: GitHub.
Appendix: source
Thrown at crates/language_models/src/provider/ollama.rs:407
.extract_if(.., |x| matches!(x, MessageContent::ToolResult(..)))
{
match tool_result {
MessageContent::ToolResult(tool_result) => {
let images = tool_result
.images()
.map(|image| image.source.to_string())
.collect::<Vec<_>>();
messages.push(ChatMessage::Tool {
tool_name: tool_result.tool_name.to_string(),
content: tool_result.text_contents(),
images: if images.is_empty() {
None
} else {
Some(images)
},
})
}
_ => unreachable!("Only tool result should be extracted"),
}
}
if !msg.content.is_empty() {
messages.push(ChatMessage::User {
content: msg.string_contents(),
images: if images.is_empty() {
None
} else {
Some(images)
},
})
}
}
Role::Assistant => {
let mut text_content = String::new();
let mut thinking = None;
let mut tool_calls = Vec::new();
for content in msg.content.into_iter() {View on GitHub (pinned to 916fc2b8cb)