{"record":{"id":"157acdd3a5a9db8b","repo":"Hmbown/CodeWhale","slug":"backoff-last-error","errorCode":null,"errorMessage":"{backoff.last_error}","messagePattern":"\\{backoff\\.last_error\\}","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":3642,"sourceCode":"                continue;\n            }\n\n            // Authority validated immediately above for this same source.\n            if self\n                .connections\n                .get(&name)\n                .is_some_and(McpConnection::is_transport_ready)\n            {\n                continue;\n            }\n            // Inside its cooldown a failed server costs nothing and still\n            // tells the truth: the recorded diagnosis is replayed so the row\n            // keeps reading `error`, rather than going quiet and looking\n            // healthy because nobody asked.\n            if let Some(backoff) = self.connect_backoff.get(&name)\n                && std::time::Instant::now() < backoff.retry_after\n            {\n                errors.push((name, anyhow::anyhow!(backoff.last_error.clone())));\n                continue;\n            }\n            if self.connecting.contains(&name) {\n                // An earlier pass spawned this connect and it has not\n                // resolved; a second pass must not spawn a duplicate.\n                continue;\n            }\n            self.drop_connection(&name, \"reconnect\");\n            self.connecting.insert(name.clone());\n            pending.push((name, server_config));\n        }\n        (pending, errors)\n    }\n\n    /// Start connects for servers an explicit tool selection named. Unlike a\n    /// boot pass the selection is the intent — cooldowns do not apply — but\n    /// servers already ready or already in flight are left alone, and plugin\n    /// authority is re-validated exactly as in","sourceCodeStart":3624,"sourceCodeEnd":3660,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp.rs#L3624-L3660","documentation":"Rather than a fixed message, this error replays the recorded last_error from a connection's exponential backoff state. When a server is in its backoff window (a prior connect attempt failed and retry_after has not elapsed), any re-connect attempt immediately fails with the original diagnosis so the status row keeps showing why the server is down.","triggerScenarios":"Calling the pool's connect/refresh pass for a server whose name is in connect_backoff and whose backoff.retry_after is still in the future.","commonSituations":"A required MCP server crashed on startup (bad command, auth failure) and the UI re-checks status before the backoff timer expires; automated polling of server status during repeated failures.","solutions":["Wait until backoff.retry_after elapses, then the connect is attempted for real and this replay stops","Fix the underlying cause recorded in backoff.last_error (check the original message for the real failure)","Restart the session or remove the server from config if it should no longer be connected"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check backoff state before attempting a connect\nif let Some(b) = pool.connect_backoff.get(&name) {\n    if std::time::Instant::now() < b.retry_after { return Err(anyhow!(b.last_error.clone())); }\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if std::time::Instant::now() < backoff.retry_after => schedule_retry(backoff.retry_after - Instant::now()),\n    other => other,\n}","preventionTips":["Surface backoff.retry_after in the UI so users know when the next attempt happens","Fix the root cause in last_error rather than retrying blindly","Use exponential backoff with jitter to avoid retry storms"],"tags":["mcp","backoff","retry","connection"],"backgroundTag":"request-timeout","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}