Hmbown/CodeWhale · error

Reviewed plugin MCP authentication failed (provider details…

Error message

Reviewed plugin MCP authentication failed (provider details suppressed)

What it means

When building resolved HTTP headers for a reviewed plugin's MCP server, OAuth-based authentication failed. Because the server came from a reviewed plugin, `suppress_server_error_details` is set, so the library replaces the underlying OAuth error with this generic message to avoid leaking provider or endpoint details to the user.

Solutions

  1. Re-run the plugin connection with full error details enabled (suppress_server_error_details = false) to see the real OAuth failure
  2. Re-authenticate / clear cached OAuth tokens so a fresh token flow starts
  3. Verify network reachability of the MCP server's OAuth issuer/token endpoint
  4. Check the plugin's OAuth client configuration (client id, scopes, issuer URL)

Example fix

// before
let headers = transport.auth.resolved_headers().await?; // opaque suppressed error
// after
match transport.auth.resolved_headers().await {
    Ok(h) => h,
    Err(e) if e.to_string().contains("authentication failed") => {
        // retry with details unsuppressed / re-auth flow
        eprintln!("OAuth for reviewed plugin needs re-auth; rerun with diagnostics enabled");
        return Err(e);
    }
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: retry

Validate before calling

// Before connecting, sanity-check OAuth inputs for the reviewed plugin
if oauth_issuer_unreachable(&plugin.oauth).await {
    eprintln!("token endpoint unreachable; fix network or plugin OAuth config first");
}

Try / catch

match transport.auth.resolved_headers().await {
    Ok(h) => h,
    Err(e) if e.to_string().contains("provider details suppressed") => {
        // Re-authenticate, then retry once with details unsuppressed for diagnosis
        refresh_oauth_tokens(&mut transport.oauth).await?;
        transport.suppress_server_error_details = false;
        transport.auth.resolved_headers().await?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `resolved_headers` (crates/tui/src/mcp/http.rs:115) finds no static Authorization header and calls `oauth.authorization_header()`, which errors (expired/invalid token, unreachable token endpoint, missing client credentials) while server error details are suppressed.

Common situations: An OAuth access token expired and refresh failed; the token endpoint is unreachable (offline, firewall, DNS); the reviewed plugin's OAuth client credentials are wrong or revoked; clock skew invalidating token expiry.

Understand the failure class

Related errors


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

Appendix: source

Thrown at crates/tui/src/mcp/http.rs:115

        if !mcp_headers_have_authorization(&headers)
            && let Some(env_var) = self.bearer_token_env_var.as_deref()
            && let Ok(token) = self.reviewed_plugin.as_ref().map_or_else(
                || std::env::var(env_var),
                |source| source.host_environment.var(env_var),
            )
        {
            let token = token.trim();
            if !token.is_empty() {
                headers.insert("Authorization".to_string(), format!("Bearer {token}"));
            }
        }
        if !mcp_headers_have_authorization(&headers)
            && let Some(oauth) = &self.oauth
        {
            let authorization = match oauth.authorization_header().await {
                Ok(authorization) => authorization,
                Err(_) if self.suppress_server_error_details => {
                    anyhow::bail!(
                        "Reviewed plugin MCP authentication failed (provider details suppressed)"
                    )
                }
                Err(error) => return Err(error),
            };
            if let Some(value) = authorization {
                headers.insert("Authorization".to_string(), value);
            }
        }
        Ok(headers)
    }
}

pub(super) fn mcp_headers_have_authorization(headers: &HashMap<String, String>) -> bool {
    headers
        .keys()
        .any(|key| key.trim().eq_ignore_ascii_case("authorization"))
}

View on GitHub (pinned to 73e0f67d83)