nikivdev/code · error
jj log failed in {}
Error message
jj log failed in {} What it means
This error is raised when the `jj log -r '@ | @-' --no-graph -T bookmarks` command exits with a non-zero status while collecting jj bookmark names for a PR preview. It means jj itself ran (it was found on PATH and started) but reported failure, e.g. because the directory is not a jj workspace, the working copy is corrupt, or the repo uses a different VCS. The library bails out rather than silently treating the preview as having no bookmarks.
Source
Thrown at src/pr_preview.rs:1440
)
})?;
if !repo_root.join(".git").exists() {
bail!(
"derived shared repo root {} does not contain .git",
repo_root.display()
);
}
Ok(repo_root)
}
fn detect_jj_head_ref(workspace_root: &Path) -> Result<String> {
let output = Command::new("jj")
.current_dir(workspace_root)
.args(["log", "-r", "@ | @-", "--no-graph", "-T", "bookmarks"])
.output()
.with_context(|| format!("failed to run jj log in {}", workspace_root.display()))?;
if !output.status.success() {
bail!("jj log failed in {}", workspace_root.display());
}
let mut bookmarks = parse_jj_bookmark_tokens(&String::from_utf8_lossy(&output.stdout));
bookmarks.sort();
bookmarks.dedup();
if let Some(leaf) = bookmarks
.iter()
.find(|token| token.starts_with("review/") || token.starts_with("codex/"))
{
return Ok(leaf.clone());
}
if let Some(stable) = bookmarks
.iter()
.find(|token| !token.starts_with("recovery/") && !token.starts_with("backup/"))
{
return Ok(stable.clone());
}
bookmarks.into_iter().next().ok_or_else(|| {
anyhow::anyhow!(View on GitHub (pinned to a747e741ae)
Solutions
- Run `jj log -r '@ | @-' --no-graph -T bookmarks` manually in the reported directory to see jj's real error message.
- If the directory is meant to be a git repo, initialize or colocate jj with `jj git init --colocate` (or skip the jj path if the project uses git).
- Run `jj workspace update-stale` or `jj workspace root` checks if the working copy is stale; re-clone or re-init if .jj is corrupt.
- Verify your jj version supports the flags used and upgrade/downgrade jj accordingly.
Example fix
// before
bail!("jj log failed in {}", workspace_root.display());
// after
let has_jj = workspace_root.join(".jj").exists();
if !output.status.success() {
if !has_jj {
return Ok(Vec::new()); // gracefully degrade: not a jj workspace
}
bail!("jj log failed in {}: {}", workspace_root.display(),
String::from_utf8_lossy(&output.stderr));
} Defensive patterns
Strategy: fallback
Validate before calling
let is_jj_ws = workspace_root.join(".jj").exists();
if !is_jj_ws {
// skip jj bookmark collection, use git fallback
} Try / catch
// handle the anyhow error and degrade gracefully
match collect_jj_bookmarks(workspace_root) {
Ok(b) => b,
Err(_) => Vec::new(), // treat as no jj bookmarks
} Prevention
- Check for .jj directory before invoking jj commands.
- Pin/test the jj version your tooling relies on.
- Run jj commands against the workspace root, not subdirectories.
When it happens
Trigger: Calling the PR preview code path in a directory that is not a jj workspace (`jj log` exits with 'not a workspace'), a corrupted or locked jj working copy (.jj directory missing or stale), or a jj version/config that rejects the `-T bookmarks` template or the `@ | @-` revision set.
Common situations: Running the tool inside a plain git repository (no .jj), running it in a subdirectory outside the workspace root, a jj upgrade that changed template syntax, or a leftover partial jj workspace after an interrupted operation.
Related errors
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/c75ec472a2fd7645.
Report an issue: GitHub.