{"record":{"id":"ffb78eb39ba20ff8","repo":"Hmbown/CodeWhale","slug":"web-is-mutually-exclusive-with-http-and-mobi","errorCode":null,"errorMessage":"--web is mutually exclusive with --http and --mobile","messagePattern":"--web is mutually exclusive with --http and --mobile","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":1287,"sourceCode":"        (false, None) => ServeBindHost {\n            host: \"127.0.0.1\".to_string(),\n            mobile_rebound_to_lan: false,\n        },\n    }\n}\n\nfn validate_serve_mode_selection(\n    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 {","sourceCodeStart":1269,"sourceCodeEnd":1305,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/lib.rs#L1269-L1305","documentation":"The serve flag matrix treats --web (the loopback-only web UI) as mutually exclusive with both --http and --mobile. All three select the HTTP transport, but web mode has its own hard loopback constraint while mobile mode deliberately widens the bind, so combining them produces contradictory bind semantics and is rejected before the server starts.","triggerScenarios":"`codewhale serve --web --http`, `codewhale serve --web --mobile`; scripts or docs that append mode flags cumulatively; enabling a web UI plus mobile remote control in one invocation.","commonSituations":"Copy-paste layering of flags from different docs; toggling between UI modes without clearing the previous flag; config-driven launchers that pass every enabled mode at once.","solutions":["Choose exactly one HTTP flavor: --web, --http, or --mobile","Run a second codewhale serve process on another port if you genuinely need two HTTP surfaces","Fix wrapper scripts so exactly one of the three flags is emitted"],"exampleFix":"# before\ncodewhale serve --web --mobile\n\n# after\ncodewhale serve --web           # loopback-only web UI","handlingStrategy":"validation","validationCode":"count=0\n$WEB    && count=$((count+1))\n$HTTP   && count=$((count+1))\n$MOBILE && count=$((count+1))\n[ \"$count\" -gt 1 ] && { echo 'choose one of --web/--http/--mobile'; exit 2; }","typeGuard":"fn web_http_disjoint(web: bool, http: bool, mobile: bool) -> bool {\n    !(web && (http || mobile))\n}","tryCatchPattern":null,"preventionTips":["Treat the three HTTP flavors as one mutually exclusive choice in launchers","Lint serve invocations in CI flag-matrix tests"],"tags":["serve","web","cli","mutual-exclusion"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}