zed-industries/zed · error · anyhow::Error

Context server not initialized

Error message

Context server not initialized

What it means

The context-server entry exists in the store, but `server.client()` returned None — no JSON-RPC client is currently established for the MCP connection. The server is registered but not initialized: it is still starting up, or it has shut down and its client was cleared. The tool call fails before any request is sent.

Source

Thrown at crates/agent/src/tools/context_server_registry.rs:365

        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,
                arguments
            );

            let request = protocol.request::<context_server::types::requests::CallTool>(
                context_server::types::CallToolParams {
                    name: tool_name,
                    arguments,

View on GitHub (pinned to bc538def45)

Solutions

  1. Gate tool invocation on the server reaching a connected state (await the store's running/initialized status).
  2. Check server logs for handshake failures or instant exits and fix the launch command.
  3. Restart the server or extension, then retry the tool once the connection is up.
  4. For slow servers, surface a 'still starting' state instead of failing outright.

Example fix

// before
let Some(protocol) = server.client() else {
    return Err(anyhow::anyhow!("Context server not initialized").into());
};
// after
let Some(protocol) = server.client() else {
    return Err(anyhow::anyhow!("server {} is still connecting — retry once it is initialized", self.server_id.0).into());
};
Defensive patterns

Strategy: validation

Validate before calling

let Some(server) = store.read(cx).get_running_server(&server_id) else {
    anyhow::bail!("server '{server_id}' not running");
};
if server.client().is_none() {
    anyhow::bail!("server '{server_id}' still connecting — retry after initialization");
}

Type guard

fn is_context_server_connected(
    store: &Entity<ContextServerStore>,
    server_id: &ContextServerId,
    cx: &App,
) -> bool {
    store
        .read(cx)
        .get_running_server(server_id)
        .map(|server| server.client().is_some())
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: Invoking the tool in the window between server registration and connection handshake; after the server process exited or was stopped; races at agent startup when tools are listed before the server is live.

Common situations: Slow-starting servers (npx downloading packages) called immediately after activation; servers that crash instantly leaving stale entries; stale tool caches after a server restart.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/aefcc13ab318294a. Report an issue: GitHub.