Hmbown/CodeWhale · warning · anyhow::Error
MCP configuration changed while connecting
Error message
MCP configuration changed while connecting {name}; retry against the current config What it means
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.
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
Example fix
// retry against current config
match pool.store_ready_connection(name.clone(), conn) {
Err(e) if e.to_string().contains("retry against the current config") => {
pool.connect_server(&name).await?; // rebuild with current catalog
}
other => other?,
} Defensive patterns
Strategy: retry
Validate before calling
// before storing, confirm the generation still matches
if connection.catalog_generation != pool.current_catalog_generation() {
pool.connect_server(&name).await?; // rebuild against current config
} Try / catch
match store_ready_connection(name, conn) {
Err(e) if e.to_string().contains("retry against the current config") => retry_connect(name),
other => other,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- computer_observation_required
- Failed to call MCP method
- Failed to store MCP connection for
- MCP configuration changed; reload it before connecting this…
- MCP configuration changed; reload it before retrying this…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/c9cd022295cbdcd9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp.rs:3308
Err(error) => {
self.note_connect_failure(server_name, &error);
return Err(error);
}
};
connection.catalog_generation = self.current_catalog_generation();
self.store_ready_connection(server_name.to_string(), connection)?;
self.connections
.get_mut(server_name)
.ok_or_else(|| anyhow::anyhow!("Failed to store MCP connection for {server_name}"))
}
pub(crate) fn store_ready_connection(
&mut self,
name: String,
connection: McpConnection,
) -> Result<()> {
self.require_server(&name)?;
anyhow::ensure!(
connection.catalog_generation == self.current_catalog_generation(),
"MCP configuration changed while connecting {name}; retry against the current config"
);
if let Some(source) = connection.config().reviewed_plugin.as_ref() {
source.validate_before_use(&name, "use")?;
}
// A successful connect settles the auth question for this server,
// and the cooldown with it — plus any supervisor dead mark or park,
// since a stored-ready connection is alive by construction.
self.connecting.remove(&name);
self.connect_backoff.remove(&name);
self.supervised_dead.remove(&name);
self.supervised_parked.remove(&name);
if self.needs_auth_servers.remove(&name) {
self.needs_auth_generation = self.needs_auth_generation.wrapping_add(1);
}
self.connections.insert(name, connection);
Ok(())View on GitHub (pinned to 73e0f67d83)