{"record":{"id":"17591007b8a8cbd5","repo":"Hmbown/CodeWhale","slug":"reviewed-plugin-mcp-authentication-failed-provide","errorCode":null,"errorMessage":"Reviewed plugin MCP authentication failed (provider details suppressed)","messagePattern":"Reviewed plugin MCP authentication failed \\(provider details suppressed\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/http.rs","lineNumber":115,"sourceCode":"        if !mcp_headers_have_authorization(&headers)\n            && let Some(env_var) = self.bearer_token_env_var.as_deref()\n            && let Ok(token) = self.reviewed_plugin.as_ref().map_or_else(\n                || std::env::var(env_var),\n                |source| source.host_environment.var(env_var),\n            )\n        {\n            let token = token.trim();\n            if !token.is_empty() {\n                headers.insert(\"Authorization\".to_string(), format!(\"Bearer {token}\"));\n            }\n        }\n        if !mcp_headers_have_authorization(&headers)\n            && let Some(oauth) = &self.oauth\n        {\n            let authorization = match oauth.authorization_header().await {\n                Ok(authorization) => authorization,\n                Err(_) if self.suppress_server_error_details => {\n                    anyhow::bail!(\n                        \"Reviewed plugin MCP authentication failed (provider details suppressed)\"\n                    )\n                }\n                Err(error) => return Err(error),\n            };\n            if let Some(value) = authorization {\n                headers.insert(\"Authorization\".to_string(), value);\n            }\n        }\n        Ok(headers)\n    }\n}\n\npub(super) fn mcp_headers_have_authorization(headers: &HashMap<String, String>) -> bool {\n    headers\n        .keys()\n        .any(|key| key.trim().eq_ignore_ascii_case(\"authorization\"))\n}","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/http.rs#L97-L133","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Re-run the plugin connection with full error details enabled (suppress_server_error_details = false) to see the real OAuth failure","Re-authenticate / clear cached OAuth tokens so a fresh token flow starts","Verify network reachability of the MCP server's OAuth issuer/token endpoint","Check the plugin's OAuth client configuration (client id, scopes, issuer URL)"],"exampleFix":"// before\nlet headers = transport.auth.resolved_headers().await?; // opaque suppressed error\n// after\nmatch transport.auth.resolved_headers().await {\n    Ok(h) => h,\n    Err(e) if e.to_string().contains(\"authentication failed\") => {\n        // retry with details unsuppressed / re-auth flow\n        eprintln!(\"OAuth for reviewed plugin needs re-auth; rerun with diagnostics enabled\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","handlingStrategy":"retry","validationCode":"// Before connecting, sanity-check OAuth inputs for the reviewed plugin\nif oauth_issuer_unreachable(&plugin.oauth).await {\n    eprintln!(\"token endpoint unreachable; fix network or plugin OAuth config first\");\n}","typeGuard":null,"tryCatchPattern":"match transport.auth.resolved_headers().await {\n    Ok(h) => h,\n    Err(e) if e.to_string().contains(\"provider details suppressed\") => {\n        // Re-authenticate, then retry once with details unsuppressed for diagnosis\n        refresh_oauth_tokens(&mut transport.oauth).await?;\n        transport.suppress_server_error_details = false;\n        transport.auth.resolved_headers().await?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Refresh OAuth tokens proactively before expiry","Verify reviewed plugins' issuer/token endpoints are reachable in your environment","Temporarily disable error-detail suppression when diagnosing auth failures"],"tags":["mcp","oauth","authentication","http"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}