{"record":{"id":"b23369056e660154","repo":"Hmbown/CodeWhale","slug":"no-diff-to-review","errorCode":null,"errorMessage":"No diff to review.","messagePattern":"No diff to review\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/tui/src/lib.rs","lineNumber":7933,"sourceCode":"    let input = input.trim();\n    if input.is_empty() {\n        bail!(\"No session selected.\");\n    }\n    let idx: usize = input\n        .parse()\n        .map_err(|_| anyhow::anyhow!(\"Invalid input\"))?;\n    let session = sessions\n        .get(idx.saturating_sub(1))\n        .ok_or_else(|| anyhow::anyhow!(\"Selection out of range\"))?;\n    Ok(session.id.clone())\n}\n\nasync fn run_review(config: &Config, args: ReviewArgs) -> Result<()> {\n    use crate::client::DeepSeekClient;\n\n    let diff = collect_diff(&args)?;\n    if diff.trim().is_empty() {\n        bail!(\"No diff to review.\");\n    }\n    validate_review_receipt_args(&args)?;\n    if args.check_receipt {\n        return run_review_receipt_check(&diff, &args);\n    }\n\n    let model = resolve_review_model(config, args.model.as_deref());\n    let route = resolve_cli_exec_route(config, &model, &diff, args.model.is_none()).await?;\n    let execution_config = config_for_cli_route(config, &route);\n    let route_provider = execution_config.provider_identity_for(route.provider);\n    let model = route.model.clone();\n    let user_prompt =\n        format!(\"Review the following diff and provide feedback:\\n\\n{diff}\\n\\nEnd of diff.\");\n    let reasoning_effort = route.reasoning_effort.and_then(|effort| {\n        cli_reasoning_effort_value_for_prompt(&execution_config, &model, effort, &user_prompt)\n    });\n\n    let system = SystemPrompt::Text(","sourceCodeStart":7915,"sourceCodeEnd":7951,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/lib.rs#L7915-L7951","documentation":"run_review() first collects the diff via collect_diff() — plain `git diff`, plus `--cached` with --staged, `base...HEAD` with --base, and an optional `--path` filter — and bails when the result trims to empty. There is nothing for the review model to look at, so the command aborts before model/route resolution.","triggerScenarios":"Clean working tree with no --staged/--base (default diff empty); `--staged` with nothing staged; a `--base` equal to HEAD; or a `--path` filter matching no changes.","commonSituations":"Committing everything just before reviewing; forgetting --staged when all changes are staged; reviewing in the wrong repo/directory; a mistyped pathspec.","solutions":["Unstaged changes: ensure the tree differs from the index, or pass `--staged` when changes are staged","Review a committed change with `--base` (e.g. `--base HEAD~1`)","Check the `--path` filter matches files that actually changed (`git status`)","Confirm you are inside the intended git repository"],"exampleFix":"// before: everything already committed, tree is clean\n$ git commit -am wip && codewhale review\nError: No diff to review.\n\n// after: review the just-committed change against its parent\n$ codewhale review --base HEAD~1","handlingStrategy":"validation","validationCode":"# mirror collect_diff's selection before invoking codewhale review\nif git diff --quiet && git diff --cached --quiet; then\n  echo 'nothing to review: clean tree, nothing staged' >&2; exit 2\nfi\ncodewhale review","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Decide the diff source (tree, --staged, --base) before running review","Gate automation on `git diff --quiet` so an empty review is a skip, not a crash"],"tags":["review","git","diff","empty-input"],"backgroundTag":"empty-diff","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}