Hmbown/CodeWhale · error · StreamableSendError::Other

MCP server rejected the request with ; the session is no…

Error message

MCP server {} rejected the request with {status}; the session is no longer accepted. {hint}

What it means

After a failed OAuth refresh attempt (previous case) is exhausted, or when the auth path is exhausted, a rejected status on the MCP POST means the server no longer accepts the session. The client surfaces the masked server URL, the status, and a hint tailored to whether OAuth is configured, telling the developer the session must be re-established.

Solutions

  1. Re-authenticate / re-run the OAuth flow for the MCP server
  2. If OAuth is not configured but the server requires auth, configure OAuth credentials
  3. Retry the request so a fresh session id is negotiated
  4. Check server-side session/auth configuration and logs
Defensive patterns

Strategy: retry

Try / catch

match client.send(request).await {
    Err(e) if e.to_string().contains("session is no longer accepted") => {
        // start a fresh session (drop stale session id) and retry once
        client.reset_session();
        client.send(request).await
    }
    other => other,
}

Prevention

When it happens

Trigger: send() receives an auth-rejection status (e.g. 401/403) from the MCP server's POST response after the refresh-and-retry path did not apply or completed, and unauthorized_session_hint() builds guidance based on whether OAuth is configured.

Common situations: Server restarted and invalidated the session id; session revoked server-side; tokens expired and no OAuth configured; stale session id replayed after server state loss.

Related errors


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

Appendix: source

Thrown at crates/tui/src/mcp/streamable_http.rs:128

            if status == StatusCode::UNAUTHORIZED || status == StatusCode::FORBIDDEN {
                if !retried && let Some(oauth) = self.auth.oauth.as_ref() {
                    match oauth.force_refresh().await {
                        Ok(()) => {
                            retried = true;
                            continue;
                        }
                        Err(refresh_error) => {
                            return Err(StreamableSendError::Other(anyhow::anyhow!(
                                "MCP server {} rejected the request with {status} and refreshing the OAuth session failed: {refresh_error:#}. {hint}",
                                mask_url_secrets(&self.url),
                                hint = oauth_refresh_failed_hint(),
                            )));
                        }
                    }
                }
                let hint = unauthorized_session_hint(self.auth.oauth_configured);
                return Err(StreamableSendError::Other(anyhow::anyhow!(
                    "MCP server {} rejected the request with {status}; the session is no longer accepted. {hint}",
                    mask_url_secrets(&self.url),
                )));
            }

            if !status.is_success() {
                let body_excerpt = bounded_body_excerpt(response, ERROR_BODY_PREVIEW_BYTES).await;
                let stale_session = self.session_id.is_some()
                    && is_streamable_http_stale_session_status(status, &body_excerpt);
                let body_excerpt = self.auth.server_error_preview(&body_excerpt);
                if stale_session {
                    return Err(StreamableSendError::StaleSession(format!(
                        "status={status} body={body_excerpt}"
                    )));
                }
                if is_streamable_http_incompatible_status(status) {
                    return Err(StreamableSendError::Incompatible(format!(
                        "status={status} body={body_excerpt}"

View on GitHub (pinned to 73e0f67d83)