nikivdev/code · error

jj bookmark set failed: {}

Error message

jj bookmark set failed: {}

What it means

Raised when the explicit `jj bookmark set <head>` command used to move the PR-head bookmark exits non-zero. The tool wraps both trimmed stderr and stdout into the message so the jj diagnostic is preserved. This is a dedicated, more specific wrapper than the generic `jj {} failed` for the PR-head bookmark step.

Source

Thrown at src/commit.rs:8634

        // Ensure bookmark points at the commit, then push it.
        // If jj is unhealthy (store/index/template issues), fall back to git push.
        let jj_result = (|| -> Result<()> {
            let set_output = Command::new("jj")
                .current_dir(repo_root)
                .args([
                    "bookmark",
                    "set",
                    head,
                    "-r",
                    commit_sha,
                    "--allow-backwards",
                ])
                .output()
                .context("failed to run jj bookmark set for PR head")?;
            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()
                );

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the combined stderr/stdout after 'jj bookmark set failed:'
  2. Run `jj bookmark set <name> -r <rev>` manually to see the full error
  3. Check the bookmark name for invalid characters or conflicts (`jj bookmark list`)
  4. Update the workspace (`jj st`) and retry the operation

Example fix

// before
Error: jj bookmark set failed: Error: Failed to set bookmark
// after
$ jj st                       # sync working copy
$ jj bookmark list            # inspect conflicts
$ tool create-review          # retry
Defensive patterns

Strategy: try-catch

Validate before calling

let st = Command::new("jj").args(["st"]).output()?;
if !st.status.success() {
    return Err(anyhow!("jj workspace stale; run `jj st` before bookmark ops"));
}
// validate bookmark name charset up-front
if !head.chars().all(|c| c.is_ascii_alphanumeric() || "-_/".contains(c)) {
    return Err(anyhow!("invalid bookmark name: {head}"));
}

Try / catch

if let Err(e) = result {
    let msg = e.to_string();
    if msg.contains("bookmark set failed") {
        eprintln!("inspect `jj bookmark list` for conflicts; retry after `jj st`");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: During PR-head setup, `Command::new(jj).args(["bookmark", "set", ...])` returns a failing status — e.g. the target revision is unresolvable, the bookmark name is invalid/conflicting, or the workspace is stale.

Common situations: Bookmark name colliding with an existing bookmark on another commit without conflict resolution flags; invalid characters in generated bookmark names; jj workspace out of date; wrong revision id passed by an upstream bug.

Related errors


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