zed-industries/zed · error · anyhow::Error
{e}
Error message
{e} What it means
The MCP tool's input never arrived: `input.recv()` failed because the sending side of the tool-input channel was dropped without sending a value. The error string is the receive error ('channel closed'). In practice the agent loop aborted the tool call — run cancelled, thread shutdown, or the call discarded upstream — before delivering input.
Source
Thrown at crates/agent/src/tools/context_server_registry.rs:358
input: ToolInput<serde_json::Value>,
event_stream: ToolCallEventStream,
cx: &mut App,
) -> Task<Result<AgentToolOutput, AgentToolOutput>> {
let Some(server) = self.store.read(cx).get_running_server(&self.server_id) else {
return Task::ready(Err(anyhow::anyhow!("Context server not found").into()));
};
let tool_name = self.tool.name.clone();
let tool_id = mcp_tool_id(&self.server_id.0, &self.tool.name);
let display_name = self.tool.name.clone();
let initial_title = self.initial_title(serde_json::Value::Null, cx);
let authorize =
event_stream.authorize_third_party_tool(initial_title, tool_id, display_name, cx);
cx.spawn(async move |cx| {
let input = input
.recv()
.await
.map_err(|e| anyhow::anyhow!(e.to_string()))?;
authorize
.await
.map_err(|e| anyhow::anyhow!(e.to_string()))?;
let Some(protocol) = server.client() else {
return Err(anyhow::anyhow!("Context server not initialized").into());
};
let arguments = if let serde_json::Value::Object(map) = input {
Some(map.into_iter().collect())
} else {
None
};
log::trace!(
"Running tool: {} with arguments: {:?}",
tool_name,View on GitHub (pinned to bc538def45)
Solutions
- Map it to 'tool call aborted' — never retry the MCP call with empty or guessed input.
- Ensure callers either send input or cancel explicitly, and that cancellation propagates cleanly.
- In tests, always supply a ready input value instead of a dropped channel.
Example fix
// before
let input = input.recv().await.map_err(|e| anyhow::anyhow!(e.to_string()))?;
// after
let input = match input.recv().await {
Ok(value) => value,
Err(_) => return Err(anyhow::anyhow!("tool input dropped — call was aborted").into()),
}; Defensive patterns
Strategy: try-catch
Try / catch
let input = match input.recv().await {
Ok(value) => value,
Err(_) => return Err(anyhow::anyhow!("tool call aborted before input arrived").into()),
}; Prevention
- Always send a ToolInput value or cancel the call explicitly.
- In tests, provide ready input instead of a dropped channel.
- Propagate cancellation instead of silently dropping input senders.
When it happens
Trigger: Cancelling the agent run or dropping the `ToolInput` sender between tool dispatch and input delivery; upstream errors that abandon the call; tests that construct the tool without ever providing input.
Common situations: Stop pressed right as a tool call starts; agent thread torn down mid-dispatch; streaming-input pipelines that error before the first value.
Related errors
- tool input was not fully received
- authorization channel closed
- Failed to send tool call authorization: {error}
- MCP tool cancelled by user
- Project state not found for session
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/9af283926f76234f.
Report an issue: GitHub.