{"record":{"id":"57546bba273a2b00","repo":"Hmbown/CodeWhale","slug":"mcp-pool-has-no-configuration-source-to-reload","errorCode":null,"errorMessage":"MCP pool has no configuration source to reload","messagePattern":"MCP pool has no configuration source to reload","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":3028,"sourceCode":"    }\n\n    /// If the source config file's mtime has changed since the last check,\n    /// re-read it and (only when the content hash also changed) drop all\n    /// existing connections so the next `get_or_connect` reattaches under\n    /// the new config. No-op when the pool was constructed via [`McpPool::new`]\n    /// (no source path), when stat fails, or when the file content is\n    /// byte-identical to what we last loaded. Returns `Ok(true)` if any\n    /// connections were dropped, `Ok(false)` otherwise.\n    ///\n    /// This is the lazy half of the auto-reload story for #1267: instead of a\n    /// long-lived file watcher, the next tool invocation pays a single `stat`\n    /// call (and only re-reads the file when the mtime moved). On networked\n    /// or remote filesystems where mtime granularity is poor, the hash\n    /// compare keeps us from churning connections on every check.\n    fn reload_from_config_sources(&mut self, force: bool) -> Result<bool> {\n        if self.config_sources.is_empty() {\n            if force {\n                anyhow::bail!(\"MCP pool has no configuration source to reload\");\n            }\n            return Ok(false);\n        }\n        let current_mtimes: Vec<_> = self\n            .config_sources\n            .iter()\n            .map(|path| mcp_config_mtime(path))\n            .collect();\n        if !force && current_mtimes == self.last_mtimes {\n            return Ok(false);\n        }\n        // An mtime moved, or the user explicitly requested a reload: re-read\n        // the complete global + workspace + plugin-backed config.\n        let primary = self\n            .config_sources\n            .first()\n            .context(\"MCP config source list unexpectedly empty\")?;\n        let new_config = if let Some(workspace) = self.workspace.as_deref() {","sourceCodeStart":3010,"sourceCodeEnd":3046,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp.rs#L3010-L3046","documentation":"`reload_from_config_sources(force = true)` was called but the pool has no recorded configuration sources, so there is nothing to reload. The non-forced path silently returns `Ok(false)`; only an explicit forced reload errors, because the caller demanded a reload that cannot happen.","triggerScenarios":"Calling a forced config reload (hot-reload / manual reload API) on an `McpPool` built without `config_sources` (e.g. via `McpConfig::default()` without `from_config_path*`).","commonSituations":"Programmatically constructed pools (no config file) hooked into a file-watcher reload loop; calling force-reload after sources were cleared.","solutions":["Construct the pool via `from_config_path*` so `config_sources` is populated.","Only call the forced reload when `config_sources` is non-empty; use the non-forced check otherwise.","If the pool is intentionally file-less, remove it from the reload loop instead of force-reloading."],"exampleFix":"// before\npool.reload_from_config_sources(true)?; // panics/errors when no sources\n// after\nif pool.has_config_sources() {\n    pool.reload_from_config_sources(true)?;\n}","handlingStrategy":"type-guard","validationCode":"if pool.config_sources.is_empty() {\n    // nothing to reload; skip instead of forcing\n    return Ok(false);\n}","typeGuard":"fn reloadable(pool: &McpPool) -> bool { !pool.config_sources.is_empty() }","tryCatchPattern":"match pool.reload_from_config_sources(force) {\n    Err(e) if e.to_string().contains(\"no configuration source to reload\") => Ok(false),\n    other => other,\n}","preventionTips":["Build pools that need hot-reload via from_config_path* so config_sources is set.","Only pass force=true from explicit user reload actions, not from watch loops.","Exclude programmatically-configured pools from file-watch reload registries."],"tags":["mcp","configuration","reload"],"backgroundTag":"missing-config-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}