Hmbown/CodeWhale · info

MCP SSE connect cancelled before the request completed

Error message

MCP SSE connect cancelled before the request completed

What it means

The SSE connect sent its initial HTTP GET but the cancellation token fired before the response arrived; the pending request is abandoned with this error. Cancellation wins over the in-flight request in the biased select.

Solutions

  1. Retry the connect with the same or a fresh token if cancellation was accidental
  2. Increase client connect/request timeouts if aborts fire before intended timeouts
  3. Check who cancels the token (UI abort, supervisor) and gate it on user intent
Defensive patterns

Strategy: try-catch

Try / catch

match run_sse_loop(...).await {
    Err(e) if e.to_string().contains("cancelled before the request") => { /* intentional abort */ }
    Err(e) => return Err(e.context("SSE connect failed")),
    Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: Cancelling the token while the initial `client.send(request)` to the MCP SSE endpoint is still in flight (slow server, network latency, shutdown).

Common situations: User aborts a slow-connecting MCP server; shutdown during startup; proxy/network causing multi-second connection latency before the response arrives.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/91be4bd11573aa8d. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/mcp/sse.rs:111

        auth: McpHttpAuth,
        tx: tokio::sync::mpsc::Sender<SseInbound>,
        cancel_token: tokio_util::sync::CancellationToken,
    ) -> Result<()> {
        let headers = tokio::select! {
            biased;
            _ = cancel_token.cancelled() => {
                anyhow::bail!("MCP SSE connect cancelled before authentication completed")
            }
            headers = auth.resolved_headers() => headers?,
        };
        let request = apply_safe_custom_headers(
            with_default_mcp_http_headers(client.get(&url), false),
            &headers,
        );
        let response = tokio::select! {
            biased;
            _ = cancel_token.cancelled() => {
                anyhow::bail!("MCP SSE connect cancelled before the request completed")
            }
            response = client.send(request) => response.with_context(|| {
                format!(
                    "MCP SSE connect failed (transport=http url={})",
                    mask_url_secrets(&url),
                )
            })?,
        };
        let status = response.status();
        if !status.is_success() {
            let body_excerpt = bounded_body_excerpt(response, ERROR_BODY_PREVIEW_BYTES).await;
            let body_excerpt = auth.server_error_preview(&body_excerpt);
            anyhow::bail!(
                "MCP SSE rejected (transport=http url={} status={}): {}",
                mask_url_secrets(&url),
                status,
                body_excerpt,
            );

View on GitHub (pinned to 73e0f67d83)