{"record":{"id":"2ef7b2edf74487f3","repo":"Hmbown/CodeWhale","slug":"mcp-configuration-changed-reload-it-before-connecting-this","errorCode":null,"errorMessage":"MCP configuration changed; reload it before connecting this server","messagePattern":"MCP configuration changed; reload it before connecting this server","errorType":"http","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/tui/src/runtime_api.rs","lineNumber":4329,"sourceCode":"    // best-effort reload behavior: unreadable/revoked sources fail closed.\n    let fresh_config = if query.connect {\n        Some(mcp_management_config(&state)?.0)\n    } else {\n        None\n    };\n    let Some(pool_handle) = mcp_pool_handle(&state, query.connect).await? else {\n        return Ok(Json(McpToolsResponse {\n            tools: Vec::new(),\n            connections: Vec::new(),\n        }));\n    };\n    let mut pool = pool_handle.lock().await;\n    if fresh_config\n        .as_ref()\n        .is_some_and(|config| !pool.config_matches(config))\n    {\n        let error =\n            anyhow::anyhow!(\"MCP configuration changed; reload it before connecting this server\");\n        let names = query\n            .server\n            .clone()\n            .map(|name| vec![name])\n            .unwrap_or_else(|| pool.server_names());\n        return Ok(Json(McpToolsResponse {\n            tools: Vec::new(),\n            connections: names\n                .iter()\n                .map(|name| mcp_connection_outcome(&pool, name, Some(&error)))\n                .collect(),\n        }));\n    }\n    let errors = if query.connect {\n        if let Some(server) = query.server.as_deref() {\n            match pool.get_or_connect(server).await {\n                Ok(_) => Vec::new(),\n                Err(error) => vec![(server.to_owned(), error)],","sourceCodeStart":4311,"sourceCodeEnd":4347,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_api.rs#L4311-L4347","documentation":"The MCP tools endpoint checks whether the freshly loaded MCP configuration still matches the in-memory connection pool's configuration. If it does not, it refuses to connect — even to a single named server — and returns this error in the response, telling the caller to reload the MCP configuration first.","triggerScenarios":"POSTing to the MCP tools endpoint (with or without a specific server name in query.server) while the pool_handle's config_matches(fresh_config) check fails, i.e. the MCP config changed after the pool snapshot was loaded.","commonSituations":"Editing mcp config (adding/removing servers, changing commands or env) while a Runtime API client holds an old pool handle, then attempting to connect without calling the reload endpoint.","solutions":["Call the Runtime API's MCP config reload endpoint (or restart the Runtime API) so the pool snapshot matches the fresh config.","Retry the MCP tools/connect request after reload succeeds.","If no changes were intended, compare the fresh config against what the pool was built from to find the unexpected diff.","Automate: after any mcp config write, always issue a reload before further MCP calls."],"exampleFix":"// before\nPOST /mcp/tools {\"server\": \"github\"}  // -> \"MCP configuration changed; reload...\"\n\n// after\nPOST /mcp/reload\nPOST /mcp/tools {\"server\": \"github\"}","handlingStrategy":"retry","validationCode":"let fresh = fetch_mcp_config().await?;\nlet stale = fetch_pool_config_hash().await? != hash_of(&fresh);\nif stale { call_mcp_reload().await?; }","typeGuard":null,"tryCatchPattern":"match resp.error {\n    Some(e) if e.contains(\"MCP configuration changed\") => {\n        client.reload_mcp_config().await?;\n        client.mcp_tools(query).await?;\n    }\n    other => handle(other),\n}","preventionTips":["Always reload MCP config after any edit before connecting servers","Cache a config hash client-side and reload when it changes","Restart the Runtime API when unsure whether the pool is current"],"tags":["mcp","runtime-api","stale-state"],"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"}