Hmbown/CodeWhale · error

Failed to read MCP config

Error message

Failed to read MCP config {}: {}

What it means

Thrown by `load_mcp_config` when the config file exists but cannot be read from disk (permissions, I/O error). The path and the underlying io::Error are included in the message. A non-existent path is not an error — it returns a default config.

Solutions

  1. Fix permissions on the config file (e.g. `chmod u+rw <path>` or chown to your user).
  2. Confirm the path is a regular file, not a directory (`ls -l <path>`).
  3. If it was created by root/sudo, chown it back to your user or recreate it as your user.
  4. Check the wrapped OS error for the underlying cause (EACCES, EISDIR, EIO) and address it directly.

Example fix

// before
sudo codewhale mcp add myserver -- cmd   # creates root-owned config
// after
codewhale mcp add myserver -- cmd
sudo chown $USER ~/.config/codewhale/mcp.json  # repair if needed
Defensive patterns

Strategy: try-catch

Validate before calling

let meta = std::fs::metadata(&path)?;
if !meta.is_file() { eprintln!("config path is not a regular file: {}", path.display()); }
let f = std::fs::OpenOptions::new().read(true).open(&path)?; // probe readability

Try / catch

match std::fs::read_to_string(&path) {
    Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => eprintln!("fix ownership/permissions on {}", path.display()),
    Err(e) => eprintln!("read failed: {e}"),
    Ok(_) => /* continue */,
}

Prevention

When it happens

Trigger: Any `codewhale mcp` subcommand that calls load_mcp_config when `std::fs::read_to_string(path)` fails: file exists but lacks read permission, path is a directory, or an OS-level I/O error occurs.

Common situations: Config file owned by another user or written by root; restrictive umask after running as a different user; the path points at a directory; disk/network filesystem errors; Windows file locking.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/229340faf25b669a. Report an issue: GitHub.

Appendix: source

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

            println!("  command: {exe_str}");
            println!(
                "  args:    {}serve --mcp",
                workspace.map_or(String::new(), |ws| format!("--workspace {ws} "))
            );
            println!();
            println!("Tip: Use `codewhale mcp validate` to test the connection.");
            println!("     Use `codewhale serve --http` for the HTTP/SSE runtime API instead.");
            Ok(())
        }
    }
}

fn load_mcp_config(path: &Path) -> Result<McpConfig> {
    if !path.exists() {
        return Ok(McpConfig::default());
    }
    let contents = std::fs::read_to_string(path)
        .map_err(|e| anyhow::anyhow!("Failed to read MCP config {}: {}", path.display(), e))?;
    let cfg: McpConfig = serde_json::from_str(&contents).map_err(|_| {
        anyhow::anyhow!(
            "Failed to parse MCP config {}; file contents were omitted",
            codewhale_config::quote_os_path(path)
        )
    })?;
    Ok(cfg)
}

/// Diagnostic status for an MCP server entry.
#[derive(Debug)]
enum McpServerDoctorStatus {
    Ok(String),
    Warning(String),
    Error(String),
}

impl McpServerDoctorStatus {

View on GitHub (pinned to 433685b202)