{"record":{"id":"647309c17a54d98b","repo":"Hmbown/CodeWhale","slug":"invalid-mcp-command","errorCode":null,"errorMessage":"Invalid MCP command","messagePattern":"Invalid MCP command","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/external_import.rs","lineNumber":201,"sourceCode":"            fields.keys().all(|key| ALLOWED.contains(&key.as_str())),\n            \"Source contains unsupported MCP fields; review it at its source\"\n        );\n        if let Some(oauth) = fields.get(\"oauth\").filter(|v| !v.is_null()) {\n            anyhow::ensure!(\n                oauth\n                    .as_object()\n                    .is_some_and(|map| map.keys().all(|key| key == \"client_id\")),\n                \"Source contains unsupported OAuth fields\"\n            );\n        }\n        let server: McpServerConfig = serde_json::from_value(config)\n            .map_err(|_| anyhow::anyhow!(\"Invalid MCP entry; contents omitted\"))?;\n        anyhow::ensure!(\n            server.command.is_some() != server.url.is_some(),\n            \"MCP entry must have one target\"\n        );\n        if let Some(command) = &server.command {\n            anyhow::ensure!(\n                !command.trim().is_empty() && !command.chars().any(char::is_control),\n                \"Invalid MCP command\"\n            );\n        }\n        if let Some(url) = &server.url {\n            let parsed =\n                reqwest::Url::parse(url).map_err(|_| anyhow::anyhow!(\"Invalid MCP URL\"))?;\n            anyhow::ensure!(\n                matches!(parsed.scheme(), \"http\" | \"https\")\n                    && parsed.host_str().is_some()\n                    && parsed.username().is_empty()\n                    && parsed.password().is_none(),\n                \"Unsupported MCP URL\"\n            );\n        }\n        super::validate_mcp_transport(server.transport.as_deref())\n            .map_err(|_| anyhow::anyhow!(\"Unsupported MCP transport\"))?;\n        let hard_blocked = !server.is_enabled();","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/external_import.rs#L183-L219","documentation":"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.","triggerScenarios":"`command` is empty or whitespace-only; `command` contains \\n, \\r, \\t, or other control characters (e.g. a command pasted with an embedded newline).","commonSituations":"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.","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"],"exampleFix":"// before\n{\"mcpServers\":{\"fs\":{\"command\":\"npx\\n -y server-fs\"}}}\n// after\n{\"mcpServers\":{\"fs\":{\"command\":\"npx\",\"args\":[\"-y\",\"server-fs\"]}}}","handlingStrategy":"validation","validationCode":"function commandOk(c) { return typeof c === \"string\" && c.trim().length > 0 && !/[\\u0000-\\u001f\\u007f]/.test(c); }","typeGuard":null,"tryCatchPattern":"catch, then print the command with control characters escaped to locate the offending byte","preventionTips":["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"],"tags":["mcp","command-injection","validation","security"],"backgroundTag":"invalid-argument-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}