{"record":{"id":"d5fe2f0c42495543","repo":"Hmbown/CodeWhale","slug":"required-mcp-server-failed-to-initialize","errorCode":null,"errorMessage":"required MCP server failed to initialize","messagePattern":"required MCP server failed to initialize","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":2725,"sourceCode":"            .collect();\n\n        for name in names {\n            if let Err(e) = self.get_or_connect(&name).await {\n                errors.push((name, e));\n            }\n        }\n\n        for (name, server_cfg) in &self.config.servers {\n            if server_cfg.required\n                && server_cfg.is_enabled()\n                && !self\n                    .connections\n                    .get(name)\n                    .is_some_and(McpConnection::is_ready)\n            {\n                errors.push((\n                    name.clone(),\n                    anyhow::anyhow!(\"required MCP server failed to initialize\"),\n                ));\n            }\n        }\n\n        errors\n    }\n\n    /// The single definition of an MCP tool's model-facing name.\n    ///\n    /// [`Self::all_tools`] (which builds the model catalog) and\n    /// [`Self::resolved_tool_servers`] (which tells tool inspection which\n    /// server owns a name) both call this, so a human-facing server\n    /// attribution can never drift from the name the model actually received.\n    #[must_use]\n    pub fn mcp_model_tool_name(server: &str, tool: &str) -> String {\n        format!(\"mcp_{server}_{tool}\")\n    }\n","sourceCodeStart":2707,"sourceCodeEnd":2743,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/mcp.rs#L2707-L2743","documentation":"connect_all connects every enabled configured server, then walks config.servers and pushes this error for each entry that is both required and enabled but whose connection is not is_ready() (Ready state plus catalog_authorized). It aggregates startup failures: the server either failed to connect/initialize, or connected but its reviewed-plugin catalog is not current, so it cannot satisfy its required contract.","triggerScenarios":"A required: true server whose command/URL is wrong, times out during initialize, returns an error, or whose reviewed plugin authority is stale — connect_all records (name, this error) in its Vec of per-server failures. Note connect_all returns errors rather than Err, so callers inspect the list.","commonSituations":"CI or fresh clones where a required server binary isn't installed or its env vars are absent; network-restricted environments blocking a required remote MCP server; plugin bundles updated but not re-approved; auth tokens for a required server expired.","solutions":["Check the per-server connect error that accompanies or precedes this one in the errors list (and logs) — it names the root cause; fix command path, URL, env, or auth.","Verify the server name in the required entry actually matches a connectable server definition.","If the server is optional in practice, drop the required flag so startup degrades gracefully.","For reviewed plugins, update/re-approve the bundle so catalog_authorized passes and is_ready becomes true."],"exampleFix":"# before (.mcp.json)\n{\"servers\": {\"db\": {\"command\": \"/usr/local/bin/db-mcp\", \"required\": true}}}\n# binary absent at that path -> required MCP server failed to initialize\n\n# after — correct path, or relax the requirement\n{\"servers\": {\"db\": {\"command\": \"db-mcp\", \"required\": true, \"env\": {\"PATH\": \"/opt/db/bin:$PATH\"}}}}\n# or: {\"command\": \"db-mcp\", \"required\": false}","handlingStrategy":"validation","validationCode":"// Rust: pre-flight the required server before startup\nasync fn required_servers_ready(pool: &mut McpPool) -> Result<()> {\n    for (name, cfg) in pool.config().servers.iter() {\n        if cfg.required && cfg.is_enabled() {\n            pool.get_or_connect(name).await\n                .with_context(|| format!(\"required server '{name}' failed\"))?;\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"// Rust: connect_all returns a Vec, inspect per-server entries\nlet errors = pool.connect_all().await;\nfor (name, e) in &errors {\n    if e.to_string().contains(\"required MCP server failed to initialize\") {\n        tracing::error!(\"startup blocked by required server '{name}': {e:#}\");\n    }\n}","preventionTips":["Only mark servers required when the session genuinely cannot proceed without them.","Install/authenticate required servers before launching (check binary path, env, tokens).","Treat the accompanying per-server connect errors as the root cause; this message is the aggregate.","For reviewed plugins, keep the bundle approved so is_ready() includes catalog authorization."],"tags":["mcp","startup","required","availability"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}