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

  1. Read the embedded stderr — it distinguishes rejection, auth, and network failures.
  2. `git fetch origin` then rebase or merge the branch if the push was rejected as non-fast-forward.
  3. Configure credentials (ssh key, gh auth login, or credential helper) for the environment running the push.
  4. Verify push permission on origin: `git push --dry-run origin <branch>`.
  5. 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

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


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)