Hmbown/CodeWhale · error

refusing to update existing remote branch

Error message

refusing to update existing remote branch {branch}

What it means

Before pushing, push_branch checks whether the branch already exists on the remote (ls-remote). If it does, the push is refused so dispatch never overwrites someone else's or a previous job's remote branch — pushes are create-only.

Solutions

  1. Pick a fresh unique branch name (include a timestamp or job id)
  2. Delete the existing remote branch if you own it and truly want it replaced, then retry
  3. Check the remote (`git ls-remote --heads <url>`) before choosing the branch

Example fix

// before
let branch = "codewhale/task"; // already on remote
// after
let branch = format!("codewhale/task-{}", job_id);
Defensive patterns

Strategy: validation

Validate before calling

let exists = remote_branch_exists(&url, &branch)?;
if exists { branch = format!("{}-{}", branch, unique_suffix()); }

Prevention

When it happens

Trigger: push_branch is called for a branch name that remote_branch_exists finds on the remote — e.g. re-running a job with the same generated branch name.

Common situations: Re-running a dispatch job after a partial failure, branch-name collisions between agents using a shared scheme, or a branch left over from an earlier task.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

    )
    .context("the agent patch did not apply cleanly onto the target branch")?;
    git(Some(&repo), &["rev-parse", "HEAD"]).map(|out| out.trim().to_string())
}

/// Push the prepared branch. Plain push only — `--force` is never passed, so
/// an existing branch that is not a fast-forward fails closed instead of
/// rewriting the target's history.
fn push_branch(repo: &Path, remote_url: &str, branch: &str) -> Result<()> {
    let remote_url = cloud_dispatch::validate_git_remote_url(remote_url)?;
    if cloud_dispatch::is_forge_default_branch(branch) {
        bail!("refusing to push onto the forge default branch {branch}");
    }
    if looks_like_network_remote(&remote_url) && cloud_dispatch::classify_url(&remote_url).is_none()
    {
        bail!("refusing to push to a non-forge remote");
    }
    if remote_branch_exists(&remote_url, branch)? {
        bail!("refusing to update existing remote branch {branch}");
    }
    git(
        Some(repo),
        &[
            "push",
            "--quiet",
            "--",
            &remote_url,
            &format!("HEAD:refs/heads/{branch}"),
        ],
    )
    .map(|_| ())
    .context(
        "could not push the cloud agent branch (it may need credentials or the branch may have moved)",
    )
}

fn looks_like_network_remote(url: &str) -> bool {

View on GitHub (pinned to 73e0f67d83)