Hmbown/CodeWhale · error
Failed to parse MCP config {}; file contents were omitted
Error message
Failed to parse MCP config {}; file contents were omitted What it means
load_config reads the MCP config file (user-level or workspace .codewhale/mcp.json) and deserializes it with serde into McpConfig. If the bytes are not valid JSON or do not match the McpServerConfig shape, parsing fails; the error deliberately omits file contents so secrets placed in env values are never echoed into logs.
Source
Thrown at crates/tui/src/mcp.rs:3553
pub resources: Vec<McpDiscoveredItem>,
pub prompts: Vec<McpDiscoveredItem>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct McpManagerSnapshot {
pub config_path: std::path::PathBuf,
pub config_exists: bool,
pub reload_required: bool,
pub servers: Vec<McpServerSnapshot>,
}
pub fn load_config(path: &Path) -> Result<McpConfig> {
validate_mcp_config_path(path)?;
let Some(contents) = read_mcp_config_file(path)? else {
return Ok(McpConfig::default());
};
serde_json::from_str(&contents).map_err(|_| {
anyhow::anyhow!(
"Failed to parse MCP config {}; file contents were omitted",
codewhale_config::quote_os_path(path)
)
})
}
fn read_mcp_config_file(path: &Path) -> Result<Option<String>> {
let metadata = match fs::symlink_metadata(path) {
Ok(metadata) => metadata,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),
Err(err) => {
return Err(err)
.with_context(|| format!("Failed to inspect MCP config {}", path.display()));
}
};
let file_type = metadata.file_type();
if file_type.is_symlink() || !file_type.is_file() {
anyhow::bail!("MCP config path must be a regular file: {}", path.display());View on GitHub (pinned to 8880682c63)
Solutions
- Validate the file with a JSON linter (jq . mcp.json) and fix reported syntax errors
- Check each server entry uses the expected types: command (string), args (array of strings), env (map string to string), enabled/disabled (bool)
- Remove comments and trailing commas - the file must be strict JSON
- Restore from a backup, or delete the file to fall back to McpConfig::default() and re-add servers
Example fix
// before (mcp.json)
{ "servers": { "a": { "command": "npx", "args": ["-y", "s"], } } }
// after
{ "servers": { "a": { "command": "npx", "args": ["-y", "s"] } } } Defensive patterns
Strategy: validation
Validate before calling
// Dry-run the file through the same shape before codewhale loads it:
let contents = std::fs::read_to_string(&mcp_json_path)?;
serde_json::from_str::<codewhale_tui::mcp::McpConfig>(&contents)
.context("mcp.json does not match the expected schema")?; Type guard
fn is_valid_mcp_config_json(raw: &str) -> bool {
serde_json::from_str::<codewhale_tui::mcp::McpConfig>(raw).is_ok()
} Try / catch
match load_config(&path) {
Err(e) if e.to_string().contains("Failed to parse MCP config") => {
eprintln!("mcp.json is invalid JSON; run: jq . {}", path.display());
}
other => other,
} Prevention
- Run jq over mcp.json after every hand edit
- Keep mcp.json under editor JSON validation (strict mode, no comments, no trailing commas)
- Never store secrets in mcp.json env values that would discourage error output - the parse error intentionally hides contents
When it happens
Trigger: Calling load_config (directly or via add/remove/set_server_enabled, snapshot, or manager startup) on a file with a JSON syntax error, trailing comma, comment, or wrong field types (e.g. args as a string instead of an array of strings).
Common situations: Hand-editing mcp.json and leaving a trailing comma; pasting snippets that use JSON5 features; merge-conflict markers left in the file; an editor saving a BOM-prefixed file.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- invalid JSON payload at key {MCP_SERVER_DEFINITIONS_KEY}; co
- invalid MCP server definition list in key {MCP_SERVER_DEFINI
- invalid {label} {path}: {error}
- Failed to render MCP template JSON: {e}
- Failed to write MCP config {}: {}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/ecaedb6f02a8adb9.
Report an issue: GitHub.