{"record":{"id":"c9cd022295cbdcd9","repo":"Hmbown/CodeWhale","slug":"mcp-configuration-changed-while-connecting-name-retry","errorCode":null,"errorMessage":"MCP configuration changed while connecting {name}; retry against the current config","messagePattern":"MCP configuration changed while connecting (.+?); retry against the current config","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/tui/src/mcp.rs","lineNumber":3308,"sourceCode":"            Err(error) => {\n                self.note_connect_failure(server_name, &error);\n                return Err(error);\n            }\n        };\n        connection.catalog_generation = self.current_catalog_generation();\n        self.store_ready_connection(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    pub(crate) fn store_ready_connection(\n        &mut self,\n        name: String,\n        connection: McpConnection,\n    ) -> Result<()> {\n        self.require_server(&name)?;\n        anyhow::ensure!(\n            connection.catalog_generation == self.current_catalog_generation(),\n            \"MCP configuration changed while connecting {name}; retry against the current config\"\n        );\n        if let Some(source) = connection.config().reviewed_plugin.as_ref() {\n            source.validate_before_use(&name, \"use\")?;\n        }\n        // A successful connect settles the auth question for this server,\n        // and the cooldown with it — plus any supervisor dead mark or park,\n        // since a stored-ready connection is alive by construction.\n        self.connecting.remove(&name);\n        self.connect_backoff.remove(&name);\n        self.supervised_dead.remove(&name);\n        self.supervised_parked.remove(&name);\n        if self.needs_auth_servers.remove(&name) {\n            self.needs_auth_generation = self.needs_auth_generation.wrapping_add(1);\n        }\n        self.connections.insert(name, connection);\n        Ok(())","sourceCodeStart":3290,"sourceCodeEnd":3326,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp.rs#L3290-L3326","documentation":"store_ready_connection refuses to register a freshly completed MCP connection when the tool catalog generation has advanced since the connect started. This means the MCP config was edited mid-handshake and the connection's catalog snapshot is stale, so using it would serve tools that no longer match the configured servers.","triggerScenarios":"Calling store_ready_connection (via the MCP connect flow) after a concurrent config reload bumped current_catalog_generation(); e.g. the user edited ~/.codewhale/mcp.json or toggled a reviewed plugin while a server was still connecting.","commonSituations":"User edits MCP config or enables/disables a plugin in another window while the TUI is still handshaking servers at startup; hot-reload of mcp.json racing slow server startup.","solutions":["Retry the connection: the error is intentionally self-healing — re-run the connect against the current config so a new connection is built with the latest catalog generation","Re-check the server still exists in the current config before retrying (require_server may also fail)","If it recurs, avoid editing the MCP config while the TUI is starting up, or wait for connections to settle before reloading"],"exampleFix":"// retry against current config\nmatch pool.store_ready_connection(name.clone(), conn) {\n    Err(e) if e.to_string().contains(\"retry against the current config\") => {\n        pool.connect_server(&name).await?; // rebuild with current catalog\n    }\n    other => other?,\n}","handlingStrategy":"retry","validationCode":"// before storing, confirm the generation still matches\nif connection.catalog_generation != pool.current_catalog_generation() {\n    pool.connect_server(&name).await?; // rebuild against current config\n}","typeGuard":null,"tryCatchPattern":"match store_ready_connection(name, conn) {\n    Err(e) if e.to_string().contains(\"retry against the current config\") => retry_connect(name),\n    other => other,\n}","preventionTips":["Avoid reloading MCP config while connections are mid-handshake","Bump-and-check catalog generation before storing results from background connects","Treat this error as a signal to retry, not a hard failure"],"tags":["mcp","stale-state","race-condition","config-reload"],"backgroundTag":"invalid-state-transition","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"}