Hmbown/CodeWhale · error · anyhow::Error

one or more MCP servers failed validation

Error message

one or more MCP servers failed validation

What it means

`mcp validate` connects to every enabled server via pool.connect_all(); if any connection errors, it prints one `- name: error` line per failing server to stderr and then bails with this aggregate message. The real diagnostic is the per-server lines printed just above, not the bail line itself.

Source

Thrown at crates/tui/src/lib.rs:8768

            println!("Disabled MCP server '{name}'");
            Ok(())
        }
        McpCommand::Validate => {
            let mut pool = McpPool::from_config_path_with_workspace_and_plugins(
                &config_path,
                workspace,
                std::sync::Arc::new(plugins.clone()),
            )?;
            let errors = pool.connect_all().await;
            if errors.is_empty() {
                println!("MCP config is valid. All enabled servers connected.");
                return Ok(());
            }
            eprintln!("MCP validation failed:");
            for (name, err) in errors {
                eprintln!("  - {name}: {err:#}");
            }
            bail!("one or more MCP servers failed validation");
        }
        McpCommand::AddSelf { name, workspace } => {
            let exe_path = std::env::current_exe()
                .map_err(|e| anyhow!("Cannot resolve current binary path: {e}"))?;
            let exe_str = exe_path.to_string_lossy().to_string();

            let mut args = vec!["serve".to_string(), "--mcp".to_string()];
            if let Some(ref ws) = workspace {
                args.push("--workspace".to_string());
                args.push(ws.clone());
            }

            let mut cfg = load_mcp_config(&config_path)?;
            if cfg.servers.contains_key(&name) {
                bail!(
                    "MCP server '{name}' already exists in {}. Use `codewhale mcp remove {name}` first, or choose a different --name.",
                    config_path.display()
                );

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Read the `- name: err` lines above the bail; fix or remove each named server
  2. For command servers, run the command manually to see the startup error
  3. Disable servers you do not currently need, then re-validate
  4. Re-run the OAuth flow / refresh tokens when auth failed

Example fix

# before
codewhale mcp validate
# MCP validation failed:
#   - fs: spawn npx ENOENT
# one or more MCP servers failed validation

# after
command -v npx || npm i -g npx
codewhale mcp validate
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight each enabled server before `mcp validate`
command -v node >/dev/null && command -v npx >/dev/null || echo 'node/npx missing for command servers'
for url in $(enabled_sse_urls); do curl -fsS --max-time 5 "$url" >/dev/null || echo "$url unreachable"; done

Prevention

When it happens

Trigger: Any enabled server whose command cannot spawn (bad binary path, missing node/npx), whose SSE url is unreachable, whose env or bearer token is wrong, or whose handshake exceeds the connect timeout.

Common situations: node/npx not on PATH in CI; upstream MCP package renamed or version-pinned wrong; expired OAuth/bearer tokens; firewall blocking the SSE endpoint; slow cold-start servers.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/700573ec9191dae3. Report an issue: GitHub.