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

  1. Run `jj log -r '@ | @-' --no-graph -T bookmarks` manually in the reported directory to see jj's real error message.
  2. 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).
  3. 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.
  4. 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

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.