affaan-m/ECC · error
git push failed
Error message
git push failed: {stderr} What it means
Before creating a PR, create_draft_pr_with_gh pushes the worktree branch to origin with `git push -u origin <branch>`. This error is raised when the push exits nonzero; git's stderr (e.g. rejected non-fast-forward, auth failure) is embedded in the message.
Solutions
- Read the embedded stderr — it distinguishes rejection, auth, and network failures.
- `git fetch origin` then rebase or merge the branch if the push was rejected as non-fast-forward.
- Configure credentials (ssh key, gh auth login, or credential helper) for the environment running the push.
- Verify push permission on origin: `git push --dry-run origin <branch>`.
- Check branch protection rules if the remote explicitly rejects the ref update.
Example fix
// before
create_draft_pr(&wt, "title", "body")?; // fails: diverged branch
// after
Command::new("git").arg("-C").arg(&wt.path).args(["pull","--rebase","origin",&wt.branch]).status()?;
create_draft_pr(&wt, "title", "body")?; Defensive patterns
Strategy: retry
Validate before calling
let dry = Command::new("git").arg(&wt.path).args(["push", "--dry-run", "origin", &wt.branch]).output()?;
if !dry.status.success() { eprintln!("push would fail: {}", String::from_utf8_lossy(&dry.stderr)); } Try / catch
if let Err(e) = create_draft_pr(&wt, title, body) {
let msg = e.to_string();
if msg.contains("fetch first") || msg.contains("rejected") {
// fetch + rebase, then retry once
} else if msg.contains("Permission") || msg.contains("auth") {
eprintln!("configure credentials for origin");
}
} Prevention
- Set up SSH keys or a credential helper in CI
- Fetch and rebase the branch before creating PRs
- Use `git push --dry-run` as a precheck
- Check remote write permissions for the token
When it happens
Trigger: Calling create_draft_pr with a branch that diverged from its upstream, lacks push permission to origin, is protected by branch rules, or when the remote is unreachable / credentials are missing.
Common situations: SSH key or credential helper not configured in CI; branch rejected because remote has newer commits (`! [rejected] ... fetch first`); pushing to a repo where the user has read-only access; offline environment.
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
- Base branch is not checked out in repo root (currently )
- branch name is not a valid git ref
- cannot reset a staged hunk while the file also has unstaged…
- cannot reset hunks for untracked files
- commit message cannot be empty
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/3e924eef7408af28.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/worktree/mod.rs:560
anyhow::bail!("PR title cannot be empty");
}
let base_branch = options
.base_branch
.as_deref()
.map(str::trim)
.filter(|value| !value.is_empty())
.unwrap_or(&worktree.base_branch);
let push = Command::new("git")
.arg("-C")
.arg(&worktree.path)
.args(["push", "-u", "origin", &worktree.branch])
.output()
.context("Failed to push worktree branch before PR creation")?;
if !push.status.success() {
let stderr = String::from_utf8_lossy(&push.stderr);
anyhow::bail!("git push failed: {stderr}");
}
let mut command = Command::new(gh_bin);
command
.arg("pr")
.arg("create")
.arg("--draft")
.arg("--base")
.arg(base_branch)
.arg("--head")
.arg(&worktree.branch)
.arg("--title")
.arg(title)
.arg("--body")
.arg(body);
for label in options
.labels
.iter()View on GitHub (pinned to 8321021c54)