Hmbown/CodeWhale · error · anyhow::Error

gh pr checkout #{number} failed: {stderr}

Error message

gh pr checkout #{number} failed: {stderr}

What it means

run_gh_pr_checkout runs `gh pr checkout <number>` (optionally with --repo) and bails with gh's trimmed stderr on non-zero exit. Checkout mutates local git state, so besides auth/PR problems the failure can come from the local work tree: conflicts, dirty files, or an existing branch name collision.

Source

Thrown at crates/tui/src/lib.rs:8300

        let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
        bail!("gh pr diff #{number} failed: {stderr}");
    }
    Ok(String::from_utf8_lossy(&output.stdout).to_string())
}

fn run_gh_pr_checkout(number: u32, repo: Option<&str>) -> Result<()> {
    let mut cmd = crate::dependencies::Gh::command()
        .ok_or_else(|| anyhow::anyhow!("gh not found on PATH"))?;
    cmd.arg("pr").arg("checkout").arg(number.to_string());
    if let Some(r) = repo {
        cmd.arg("--repo").arg(r);
    }
    let output = cmd
        .output()
        .map_err(|e| anyhow::anyhow!("Failed to run `gh pr checkout`: {e}"))?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
        bail!("gh pr checkout #{number} failed: {stderr}");
    }
    Ok(())
}

/// Format the PR review prompt that lands in the composer. Caps the
/// diff at 200 KiB so a massive PR doesn't blow the model's context
/// window before the user even hits Enter — they can always ask the
/// model to fetch more via `gh pr diff #N` from inside the session.
fn format_pr_prompt(number: u32, view: &GhPullRequest, diff: &str) -> String {
    const MAX_DIFF_BYTES: usize = 200 * 1024;
    let diff_section = if diff.len() > MAX_DIFF_BYTES {
        let cut = (0..=MAX_DIFF_BYTES)
            .rev()
            .find(|&i| diff.is_char_boundary(i))
            .unwrap_or(0);
        format!(
            "{}\n\n[…diff truncated at {} KiB; ask me to fetch more if needed]\n",
            &diff[..cut],

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Commit or stash local changes (`git stash -u`) and retry
  2. Run `gh auth status`; re-login if expired
  3. Confirm the PR exists: `gh pr view <number>`
  4. If a local branch name collides, remove/rename it first
  5. Read the embedded gh stderr for the exact refusal

Example fix

# before
run_gh_pr_checkout   # gh pr checkout #4242 failed: Your local changes would be overwritten

# after
git stash -u && gh pr checkout 4242   # then retry the review flow
Defensive patterns

Strategy: validation

Validate before calling

git diff --quiet && git diff --cached --quiet || { echo 'dirty tree -- stashing'; git stash -u; }
gh auth status >/dev/null 2>&1 || { echo 'gh not authenticated'; exit 1; }
gh pr view "$PR" >/dev/null 2>&1 || { echo "PR $PR not visible"; exit 1; }

Try / catch

match run_gh_pr_checkout(number, repo.as_deref()) {
    Ok(()) => { /* proceed with review */ }
    Err(e) if e.to_string().contains("would be overwritten") => { git_stash_and_retry(); }
    Err(e) => eprintln!("gh pr checkout failed: {e:#}"),
}

Prevention

When it happens

Trigger: Review flow attempting PR checkout with uncommitted local changes that conflict; gh auth expired; PR number not in the target repo; a local branch already using the name gh wants to create.

Common situations: Developer forgets to stash before reviewing; fork PRs whose head branch was deleted; running checkout from a detached HEAD; CI runners with no gh credentials.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/70ddb8cfdb104528. Report an issue: GitHub.