{"record":{"id":"d8b2d3c9b31a88b4","repo":"Hmbown/CodeWhale","slug":"failed-to-store-mcp-connection-for-server-name","errorCode":null,"errorMessage":"Failed to store MCP connection for {server_name}","messagePattern":"Failed to store MCP connection for (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":2687,"sourceCode":"            .ok_or_else(|| anyhow::anyhow!(\"Failed to find MCP server: {server_name}\"))?;\n\n        if !server_config.is_enabled() {\n            anyhow::bail!(\"Failed to connect MCP server '{server_name}': server is disabled\");\n        }\n\n        let mut connection = McpConnection::connect_with_policy(\n            server_name.to_string(),\n            server_config,\n            &self.config.timeouts,\n            self.network_policy.as_ref(),\n        )\n        .await?;\n        connection.catalog_generation = self.catalog_generation.load(Ordering::SeqCst);\n\n        self.connections.insert(server_name.to_string(), connection);\n        self.connections\n            .get_mut(server_name)\n            .ok_or_else(|| anyhow::anyhow!(\"Failed to store MCP connection for {server_name}\"))\n    }\n\n    /// Connect to all enabled servers, returning errors for failed connections\n    pub async fn connect_all(&mut self) -> Vec<(String, anyhow::Error)> {\n        let mut errors = Vec::new();\n        // Reload before taking the configured-name snapshot. Previously the\n        // first call after adding a server captured the old names, then only\n        // noticed the config change inside `get_or_connect`, delaying the new\n        // server until a second turn.\n        if let Err(err) = self.reload_if_config_changed().await {\n            errors.push((\"configuration\".to_string(), err));\n            return errors;\n        }\n        let names: Vec<String> = self\n            .config\n            .servers\n            .keys()\n            .filter(|n| self.config.servers[*n].is_enabled())","sourceCodeStart":2669,"sourceCodeEnd":2705,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/mcp.rs#L2669-L2705","documentation":"Immediately after connections.insert(server_name.to_string(), connection), get_or_connect calls connections.get_mut(server_name). Since insert with a freshly owned String key guarantees presence and &mut self prevents concurrent mutation, a None return contradicts the HashMap contract. Like the 'connection disappeared' branch above it is a defensive invariant check, not an expected runtime condition.","triggerScenarios":"Unreachable in correct code: insert immediately followed by get_mut on the same key under an exclusive borrow cannot yield None.","commonSituations":"Not hit in practice; its appearance would indicate memory corruption, a custom HashMap with broken behavior, or a refactor that moved the insert behind a fallible operation.","solutions":["Treat as an internal bug: capture logs and a reproduction and report it against the mcp module.","Audit any local modifications to get_or_connect or the connections map type.","Retry via get_or_connect once to see if it reproduces; persistent occurrence indicates corrupted state — restart the session."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust: internal invariant — report and retry once\nmatch pool.get_or_connect(name).await {\n    Err(e) if e.to_string().contains(\"Failed to store MCP connection\") => {\n        tracing::error!(\"internal HashMap invariant broken: {e:#}\");\n        pool.get_or_connect(name).await\n    }\n    o => o,\n}","preventionTips":["Consider it a defect signal — capture a reproducer for the maintainers.","Don't patch around it by inserting into pool internals from outside.","Restart the session if it recurs; state is suspect."],"tags":["mcp","invariant","internal","unreachable"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}