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
- Read the per-remote failure details in the message (stderr excerpts are included)
- Gain write access or use the remote you can push to (e.g. your fork, not upstream)
- Fix credentials: `ssh-add`, `gh auth login`, or git credential helper
- 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
- Pre-test pushability with `git push --dry-run <remote> <refspec>`
- Order remotes so the one you can definitely write to (your fork) is tried first
- Keep credentials fresh (credential helper / ssh-agent) before batch pushes
- Check branch-protection/permissions on every candidate remote
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
- No git remotes configured; cannot push PR head {}
- git push {} {} failed
- jj git push failed: {}
- git push failed
- remote '{}' already points to {} refusing to overwrite witho
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/e35d74c853924bad.
Report an issue: GitHub.