Hmbown/CodeWhale · error

gh pr create failed

Error message

gh pr create failed: {}

What it means

open_pr_github wraps a failing `gh pr create` invocation; the formatted error carries gh's failure output so a rejected PR creation (auth, branch protection, bad slug) is attributable to its cause rather than surfacing as an empty exit code.

Solutions

  1. Check gh stderr in the error; run `gh auth status` and re-authenticate if needed
  2. Verify the repo remote points at GitHub and you have push/PR rights
  3. Check if a PR for the branch already exists (`gh pr list --head <branch>`)
  4. Update the gh CLI and retry

Example fix

// before
// gh pr create failed: gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable
// after
export GH_TOKEN=$(gh auth token)
# or locally:
gh auth login
Defensive patterns

Strategy: retry

Validate before calling

let auth = Command::new("gh").args(["auth","status"]).output()?;
if !auth.status.success() { /* run gh auth login first */ }

Try / catch

match result {
    Err(e) if e.to_string().contains("gh pr create failed") => {
        // inspect sanitized stderr: re-auth, check existing PR, retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: open (via open_pr_github) runs `gh pr create` and the process exits nonzero — auth problems, no GitHub remote, PR already exists, template/base-branch issues.

Common situations: gh CLI not authenticated (GH_TOKEN missing or expired), repository has no GitHub origin, a PR already exists for the branch, blocked-by-rules base branch, or gh version too old.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/b6101893dfe1ae87. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/dispatch_runner.rs:606

    body: &str,
) -> Result<String> {
    let body_dir = tempfile::tempdir().context("could not stage the PR body")?;
    let body_file = body_dir.path().join("body.md");
    std::fs::write(&body_file, body).context("could not write the PR body")?;
    let mut command = crate::dependencies::Gh::command()
        .ok_or_else(|| anyhow!("the GitHub pull request needs the gh CLI on PATH"))?;
    command.args(gh_pr_create_argv(
        slug,
        &patch.base_branch,
        &job.branch,
        title,
        &body_file.to_string_lossy(),
    ));
    let output = command
        .output()
        .context("failed to start gh for the pull request")?;
    if !output.status.success() {
        bail!(
            "gh pr create failed: {}",
            sanitize_error(&String::from_utf8_lossy(&output.stderr))
        );
    }
    let url = String::from_utf8_lossy(&output.stdout).trim().to_string();
    if !url.starts_with("https://") {
        bail!("gh did not report a pull request URL; refusing to invent one.");
    }
    Ok(url)
}

fn open_pr_gitee(
    slug: &str,
    job: &CloudJob,
    patch: &PatchReceipt,
    title: &str,
    body: &str,
) -> Result<String> {

View on GitHub (pinned to 73e0f67d83)