{"record":{"id":"5530836d5e49ce0d","repo":"Hmbown/CodeWhale","slug":"expected-review-command","errorCode":null,"errorMessage":"expected review command","messagePattern":"expected review command","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":15885,"sourceCode":"        let receipt = crate::tools::review::build_review_receipt(\n            \"working tree\",\n            \"diff --git a/a b/a\",\n            provider,\n            &route.model,\n            &output,\n            \"{}\",\n            Vec::new(),\n        );\n        assert_eq!(receipt.provider, \"custom-a\");\n        let serialized = serde_json::to_string(&receipt).expect(\"review receipt\");\n        assert!(!serialized.contains(\"127.0.0.1\"));\n        assert!(!serialized.contains(\"local-test-key\"));\n    }\n\n    fn review_args(argv: &[&str]) -> ReviewArgs {\n        let cli = parse_cli(argv);\n        let Some(Commands::Review(args)) = cli.command else {\n            panic!(\"expected review command\");\n        };\n        args\n    }\n\n    #[test]\n    fn review_parses_provider_flag_alongside_model() {\n        let args = review_args(&[\n            \"codewhale\",\n            \"review\",\n            \"--pr\",\n            \"5709\",\n            \"--provider\",\n            \"zai\",\n            \"--model\",\n            \"GLM-5.3\",\n        ]);\n\n        assert_eq!(args.provider.as_deref(), Some(\"zai\"));","sourceCodeStart":15867,"sourceCodeEnd":15903,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/lib.rs#L15867-L15903","documentation":"Test-only panic in crates/tui/src/lib.rs:15885 inside the shared helper `review_args(argv)`. It parses the given argv and destructures `Commands::Review(args)` via let-else; if the parsed command is not Review, it panics with \"expected review command\". Every review CLI test funnels through this helper, so any change to the `review` subcommand surface fails all of them here first.","triggerScenarios":"Any argv passed to review_args parses to a non-Review variant or None — the `Commands::Review` subcommand was renamed, its flags changed arity, or a top-level flag now consumes the first tokens.","commonSituations":"Renaming the review subcommand or ReviewArgs flags; a new global flag (like `--prompt` num_args=1..) swallowing \"review\"; a test passing flags that no longer exist.","solutions":["Verify `Commands::Review(ReviewArgs)` is still a subcommand with the flags the tests pass.","Panic with the actual parsed command (`got {:?}`) inside review_args for diagnosis.","Fix the specific test argv that no longer parses, or update review_args if the variant was renamed.","Run `cargo test -p codewhale-tui --lib review_` to see which argv variants break."],"exampleFix":"// before\nlet Some(Commands::Review(args)) = cli.command else {\n    panic!(\"expected review command\");\n};\n// after\nlet Some(Commands::Review(args)) = cli.command else {\n    panic!(\"expected review command, got {:?}\", cli.command);\n};","handlingStrategy":"validation","validationCode":"fn review_args(argv: &[&str]) -> ReviewArgs {\n    match parse_cli(argv).command {\n        Some(Commands::Review(args)) => args,\n        other => panic!(\"expected review command for {argv:?}, got {other:?}\"),\n    }\n}","typeGuard":"fn as_review(cmd: &Option<Commands>) -> Option<&ReviewArgs> {\n    match cmd { Some(Commands::Review(a)) => Some(a), _ => None }\n}","tryCatchPattern":null,"preventionTips":["Include the input argv in helper panics — one helper failure hides which test broke.","Keep review subcommand flag names stable or update all review_args call sites together.","Run `cargo test -p codewhale-tui --lib review_` after touching Commands::Review."],"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"}