nikivdev/code · error

failed to push PR head {} to any remote: {}

Error message

failed to push PR head {} to any remote:
{}

What it means

Aggregated failure for the git fallback PR-head push: the tool tries pushing `<sha>:refs/heads/<head>` to each candidate remote, collecting a per-remote failure string (with stderr/stdout excerpts). If every remote attempt fails, it bails with the head name and the newline-joined list of all failures so the developer can see why each remote rejected the push.

Source

Thrown at src/commit.rs:8725

            return Ok(pr_head_selector_for_remote(repo_root, &remote, head));
        }

        let force_stderr = String::from_utf8_lossy(&force_output.stderr)
            .trim()
            .to_string();
        failures.push(format!(
            "{remote}: push='{}' force='{}'{}",
            push_stderr,
            force_stderr,
            if push_stdout.is_empty() {
                String::new()
            } else {
                format!(" stdout='{}'", push_stdout)
            }
        ));
    }

    bail!(
        "failed to push PR head {} to any remote:\n{}",
        head,
        failures.join("\n")
    );
}

fn pr_push_remote_candidates(repo_root: &Path) -> Vec<String> {
    let mut remotes: Vec<String> = git_capture_in(repo_root, &["remote"])
        .unwrap_or_default()
        .lines()
        .map(str::trim)
        .filter(|s| !s.is_empty())
        .map(|s| s.to_string())
        .collect();

    remotes.sort_by_key(|r| match r.as_str() {
        "fork" => 0u8,
        "origin" => 1u8,

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the per-remote failure details in the message (stderr excerpts are included)
  2. Gain write access or use the remote you can push to (e.g. your fork, not upstream)
  3. Fix credentials: `ssh-add`, `gh auth login`, or git credential helper
  4. Try the push manually: `git push <remote> <sha>:refs/heads/<head>` and resolve the reported rejection

Example fix

// before
Error: failed to push PR head review/pr-123 to any remote:
remote 'origin': ! [remote rejected] (protected branch hook declined)
// after
$ gh auth login && git push origin <sha>:refs/heads/review/pr-123
# or push to your fork:
$ git remote add fork git@github.com:me/repo.git
$ tool create-review
Defensive patterns

Strategy: retry

Validate before calling

fn can_push(remote: &str) -> bool {
    Command::new("git")
        .args(["ls-remote", "--exit-code", remote])
        .output()
        .map(|o| o.status.success())
        .unwrap_or(false)
}
let writable: Vec<_> = remotes.into_iter().filter(|r| can_push(r)).collect();
if writable.is_empty() { eprintln!("no pushable remote; fix auth or add your fork"); }

Try / catch

let msg = e.to_string();
for line in msg.lines().skip(1) {
    eprintln!("per-remote failure: {line}"); // surface each remote's cause
}
if msg.contains("denied") || msg.contains("auth") {
    eprintln!("run `ssh-add` / `gh auth login`, or push to a fork you own");
}

Prevention

When it happens

Trigger: All remotes returned by `pr_push_remote_candidates()` fail the direct `git push <remote> <sha>:refs/heads/<head>` attempt, and the loop ends with a non-empty `failures` Vec, triggering the final bail.

Common situations: Fork/upstream setups where the developer lacks write access to every candidate remote; protected branch rules rejecting new refs; authentication failures (no SSH key loaded, bad credential helper); remote rejecting non-fast-forward or oversized pushes.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/e35d74c853924bad. Report an issue: GitHub.