Hmbown/CodeWhale · error · anyhow::Error
Invalid MCP command
Error message
Invalid MCP command
What it means
When an entry targets a local server via `command`, the command string must be non-empty after trimming and must contain no control characters (which could smuggle newlines/escapes into process spawning). Anything failing those checks throws this error.
Solutions
- Set a concrete non-empty executable path or name (e.g. `npx`, `/usr/local/bin/server`)
- Remove embedded newlines/control characters from the command string; move argument logic into `args`
- Verify the entry: trimmed command length > 0 and no control chars
Example fix
// before
{"mcpServers":{"fs":{"command":"npx\n -y server-fs"}}}
// after
{"mcpServers":{"fs":{"command":"npx","args":["-y","server-fs"]}}} Defensive patterns
Strategy: validation
Validate before calling
function commandOk(c) { return typeof c === "string" && c.trim().length > 0 && !/[\u0000-\u001f\u007f]/.test(c); } Try / catch
catch, then print the command with control characters escaped to locate the offending byte
Prevention
- Put flags in `args`, never inline in `command`
- Paste commands into a plain-text editor first to strip line breaks
- Reject commands containing newlines in your own tooling
When it happens
Trigger: `command` is empty or whitespace-only; `command` contains \n, \r, \t, or other control characters (e.g. a command pasted with an embedded newline).
Common situations: Copy-pasting a command from a rendered page that includes line breaks; a generated config with an unset command placeholder; templates with empty command defaults.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- reviewed plugin MCP endpoint has an unsafe origin
- Unsupported MCP URL
- append_allow_rules only accepts action = "allow"
- bad_target
- Codewhale credentials directory has an unsupported component
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/647309c17a54d98b.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp/external_import.rs:201
fields.keys().all(|key| ALLOWED.contains(&key.as_str())),
"Source contains unsupported MCP fields; review it at its source"
);
if let Some(oauth) = fields.get("oauth").filter(|v| !v.is_null()) {
anyhow::ensure!(
oauth
.as_object()
.is_some_and(|map| map.keys().all(|key| key == "client_id")),
"Source contains unsupported OAuth fields"
);
}
let server: McpServerConfig = serde_json::from_value(config)
.map_err(|_| anyhow::anyhow!("Invalid MCP entry; contents omitted"))?;
anyhow::ensure!(
server.command.is_some() != server.url.is_some(),
"MCP entry must have one target"
);
if let Some(command) = &server.command {
anyhow::ensure!(
!command.trim().is_empty() && !command.chars().any(char::is_control),
"Invalid MCP command"
);
}
if let Some(url) = &server.url {
let parsed =
reqwest::Url::parse(url).map_err(|_| anyhow::anyhow!("Invalid MCP URL"))?;
anyhow::ensure!(
matches!(parsed.scheme(), "http" | "https")
&& parsed.host_str().is_some()
&& parsed.username().is_empty()
&& parsed.password().is_none(),
"Unsupported MCP URL"
);
}
super::validate_mcp_transport(server.transport.as_deref())
.map_err(|_| anyhow::anyhow!("Unsupported MCP transport"))?;
let hard_blocked = !server.is_enabled();View on GitHub (pinned to 73e0f67d83)