{"record":{"id":"1c5290161bc7fc99","repo":"Hmbown/CodeWhale","slug":"expected-exec-command","errorCode":null,"errorMessage":"expected exec command","messagePattern":"expected exec command","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":15430,"sourceCode":"        assert_eq!(execution.default_model(), \"routed-legacy-model\");\n        assert_eq!(execution.deepseek_base_url(), \"http://127.0.0.1:18183/v1\");\n        assert_eq!(execution.deepseek_api_key().unwrap(), \"legacy-root-key\");\n        for _ in 0..2 {\n            let identity = execution\n                .resolve_provider_identity(\"custom\")\n                .expect(\"legacy identity remains repeatedly resolvable\");\n            assert_eq!(identity.key, \"custom\");\n        }\n        let client =\n            crate::client::DeepSeekClient::new(&execution).expect(\"legacy execution client\");\n        assert_eq!(client.base_url(), \"http://127.0.0.1:18183/v1\");\n    }\n\n    #[test]\n    fn exec_accepts_split_prompt_words_for_windows_cmd_shims() {\n        let cli = parse_cli(&[\"codewhale\", \"exec\", \"hello\", \"world\"]);\n        let Some(Commands::Exec(args)) = cli.command else {\n            panic!(\"expected exec command\");\n        };\n\n        assert_eq!(args.prompt, vec![\"hello\", \"world\"]);\n    }\n\n    #[test]\n    fn exec_keeps_model_flag_before_split_prompt_words() {\n        let cli = parse_cli(&[\"codewhale\", \"exec\", \"--model\", \"auto\", \"hello\", \"world\"]);\n        let Some(Commands::Exec(args)) = cli.command else {\n            panic!(\"expected exec command\");\n        };\n\n        assert_eq!(args.model.as_deref(), Some(\"auto\"));\n        assert_eq!(args.prompt, vec![\"hello\", \"world\"]);\n    }\n\n    #[test]\n    fn exec_keeps_flags_before_split_prompt_words() {","sourceCodeStart":15412,"sourceCodeEnd":15448,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/lib.rs#L15412-L15448","documentation":"Test-only panic in crates/tui/src/lib.rs:15430. The test `exec_accepts_split_prompt_words_for_windows_cmd_shims` parses [\"codewhale\",\"exec\",\"hello\",\"world\"] and destructures `Commands::Exec(args)` via let-else; if parsing yields another variant or None, it panics with \"expected exec command\". The point under test is that unflagged words after `exec` stay in `args.prompt` instead of being absorbed elsewhere.","triggerScenarios":"parse_cli of `exec hello world` does not produce `Commands::Exec` — the `exec` subcommand was renamed/aliased away, or a new top-level argument captured \"exec\"/the prompt words so `cli.command` is None.","commonSituations":"Adding a global catch-all `prompt: Vec<String>` (num_args=1..) at the Cli level that eats \"exec\"; renaming `Commands::Exec`; breaking the subcommand dispatch while refactoring FeatureToggles.","solutions":["Verify `Commands::Exec(ExecArgs)` is still a declared subcommand in the Commands enum.","Panic with the actual parsed value (`got {:?}`) to identify what clap produced instead.","Ensure top-level multi-value args do not shadow the subcommand; clap only parses subcommands before free-standing positional values.","Run `cargo test -p codewhale-tui --lib exec_accepts_split_prompt_words` after any Cli struct change."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"match cli.command {\n    Some(Commands::Exec(ref args)) => assert_eq!(args.prompt, vec![\"hello\", \"world\"]),\n    other => panic!(\"expected exec command, got {other:?}\"),\n}","typeGuard":"fn as_exec(cmd: &Option<Commands>) -> Option<&ExecArgs> {\n    match cmd { Some(Commands::Exec(a)) => Some(a), _ => None }\n}","tryCatchPattern":null,"preventionTips":["Never add an unbounded top-level positional/num_args=1.. arg above subcommands.","Add debug context to destructuring panics in shared test helpers.","After editing Cli/Commands, run the exec CLI test filter before committing."],"tags":["rust","test-panic","cli-parsing","clap"],"backgroundTag":"internal-invariant-violation","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}