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
- Read the combined stderr/stdout after 'jj bookmark set failed:'
- Run `jj bookmark set <name> -r <rev>` manually to see the full error
- Check the bookmark name for invalid characters or conflicts (`jj bookmark list`)
- 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
- Sync the working copy (`jj st`) before bookmark operations
- Use deterministic, charset-safe bookmark names (e.g. review/pr-<num>)
- Check `jj bookmark list` for pre-existing conflicting bookmarks
- Re-run failing `jj bookmark set` manually to see full diagnostics
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
- jj {} failed: {}
- jj workspace corrupted
- jj git push failed: {}
- Source is not a jj workspace. Run `jj git init --colocate` i
- jj {} failed
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/0934b77f618939c7.
Report an issue: GitHub.