nikivdev/code · error

jj git push failed: {}

Error message

jj git push failed: {}

What it means

Raised when `jj git push --bookmark <head> --allow-new` used to publish the PR-head bookmark exits non-zero. The message embeds jj's combined trimmed stderr/stdout. Common underlying causes are remote authentication failures, rejected pushes (non-fast-forward, protected branch), or missing/invalid git remote configuration.

Source

Thrown at src/commit.rs:8649

            if !set_output.status.success() {
                let stderr = String::from_utf8_lossy(&set_output.stderr);
                let stdout = String::from_utf8_lossy(&set_output.stdout);
                bail!(
                    "jj bookmark set failed: {}",
                    format!("{}\n{}", stderr.trim(), stdout.trim()).trim()
                );
            }

            // We often push a brand new review/pr bookmark as the PR head.
            let push_output = Command::new("jj")
                .current_dir(repo_root)
                .args(["git", "push", "--bookmark", head, "--allow-new"])
                .output()
                .context("failed to run jj git push for PR head")?;
            if !push_output.status.success() {
                let stderr = String::from_utf8_lossy(&push_output.stderr);
                let stdout = String::from_utf8_lossy(&push_output.stdout);
                bail!(
                    "jj git push failed: {}",
                    format!("{}\n{}", stderr.trim(), stdout.trim()).trim()
                );
            }

            Ok(())
        })();
        if jj_result.is_ok() {
            // jj push uses the repo's configured/default git remote.
            // Keep plain branch head; gh can resolve this for same-repo pushes.
            return Ok(head.to_string());
        }
        let jj_error = jj_result.unwrap_err().to_string();
        let concise = jj_error
            .lines()
            .map(str::trim)
            .find(|line| !line.is_empty())
            .unwrap_or("jj failed");

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the jj push diagnostic after 'jj git push failed:'
  2. Push manually with `jj git push --bookmark <head> --allow-new` to see full output
  3. Fix remote auth: `ssh-add`, `gh auth login` (for HTTPS), or update credential helper
  4. Check remote branch-protection rules that may reject new refs

Example fix

// before
Error: jj git push failed: git: Permission denied (publickey)
// after
$ ssh-add ~/.ssh/id_ed25519
$ jj git push --bookmark review/pr-123 --allow-new
$ tool create-review          # retry
Defensive patterns

Strategy: retry

Validate before calling

let ls = Command::new("jj").args(["git", "remote", "list"]).output()?;
if !ls.status.success() || ls.stdout.is_empty() {
    return Err(anyhow!("no jj git remote configured for push"));
}
let auth = Command::new("ssh").args(["-T", "git@github.com"]).output();
let _ = auth; // best-effort credential warm-up; check ssh-agent is loaded

Try / catch

if let Err(e) = result {
    let msg = e.to_string();
    if msg.contains("publickey") || msg.contains("auth") {
        eprintln!("load SSH keys (`ssh-add`) or `gh auth login` for HTTPS");
    } else if msg.contains("rejected") {
        eprintln!("check branch protection rules blocking new refs");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: During PR-head publication, `Command::new(jj).args(["git","push","--bookmark",head,"--allow-new"])` returns a failing status.

Common situations: Expired/missing credentials for the git remote (SSH key not loaded, no credential helper); remote rejecting creation of the new bookmark due to branch protection; network/VPN blocking the remote; remote URL misconfigured after repo migration.

Related errors


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