{"record":{"id":"0d35836cf460cef8","repo":"Hmbown/CodeWhale","slug":"choose-exactly-one-server-mode-mcp-http-mo","errorCode":null,"errorMessage":"Choose exactly one server mode: --mcp, --http/--mobile/--web, or --acp","messagePattern":"Choose exactly one server mode: --mcp, --http/--mobile/--web, or --acp","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":1295,"sourceCode":"    mcp: bool,\n    http: bool,\n    mobile: bool,\n    web: bool,\n    acp: bool,\n) -> Result<bool> {\n    if http && mobile {\n        bail!(\"--http and --mobile are mutually exclusive; choose one\");\n    }\n    if web && (http || mobile) {\n        bail!(\"--web is mutually exclusive with --http and --mobile\");\n    }\n    let http_selected = http || mobile || web;\n    let selected_modes = [mcp, http_selected, acp]\n        .into_iter()\n        .filter(|selected| *selected)\n        .count();\n    if selected_modes != 1 {\n        bail!(\"Choose exactly one server mode: --mcp, --http/--mobile/--web, or --acp\");\n    }\n    Ok(http_selected)\n}\n\n#[derive(Subcommand, Debug, Clone)]\nenum McpCommand {\n    /// List configured MCP servers\n    List,\n    /// Create a template MCP config at the configured path\n    Init {\n        /// Overwrite an existing MCP config file\n        #[arg(long, default_value_t = false)]\n        force: bool,\n    },\n    /// Connect to MCP servers and report status\n    Connect {\n        /// Optional server name to connect to\n        #[arg(value_name = \"SERVER\")]","sourceCodeStart":1277,"sourceCodeEnd":1313,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/lib.rs#L1277-L1313","documentation":"validate_serve_mode_selection counts the selected transport families — mcp, the http group (--http/--mobile/--web collapse into one), and acp — and requires exactly one. This bail fires both when nothing was selected (bare `codewhale serve`) and when two different transports were requested (e.g. --mcp --acp), because one process serves exactly one protocol.","triggerScenarios":"`codewhale serve` with no mode flag at all; `codewhale serve --mcp --acp`; `codewhale serve --http --mcp`; launchers that default to passing no flags while assuming an implicit mode.","commonSituations":"Expecting MCP to be the default and omitting the flag; migrating a serve invocation between MCP and HTTP/ACP eras of the CLI; systemd/launcher units that lost their mode flag in templating.","solutions":["Pass exactly one mode: --mcp for the MCP stdio server, one of --http/--mobile/--web for the HTTP API, or --acp for the ACP server","If you need several protocols, run one codewhale serve process per mode","Check launcher templates/systemd units for a flag that renders empty"],"exampleFix":"# before\ncodewhale serve                       # or: codewhale serve --mcp --acp\n\n# after\ncodewhale serve --mcp                 # exactly one mode","handlingStrategy":"validation","validationCode":"modes=0\n$MCP && modes=$((modes+1))\n{ $HTTP || $MOBILE || $WEB; } && modes=$((modes+1))\n$ACP && modes=$((modes+1))\n[ \"$modes\" -ne 1 ] && { echo 'exactly one of --mcp / --http-family / --acp required'; exit 2; }","typeGuard":"fn serve_mode_count_ok(mcp: bool, http_selected: bool, acp: bool) -> bool {\n    [mcp, http_selected, acp].iter().filter(|s| **s).count() == 1\n}","tryCatchPattern":null,"preventionTips":["Default the mode explicitly in launcher templates so empty flags cannot reach codewhale","Run one serve process per protocol instead of combining flags"],"tags":["serve","cli","flags","server-mode"],"backgroundTag":"missing-required-flag","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}