nikivdev/code · error

{} has an empty .jj/repo pointer

Error message

{} has an empty .jj/repo pointer

What it means

For jj (Jujutsu) workspaces, the repo root is resolved via the `.jj/repo` pointer file, which holds the path to the jj repo store (absolute, or relative to `.jj/`). This error fires when that file exists but is empty after trimming, so the repo directory cannot be located.

Source

Thrown at src/pr_preview.rs:1400

fn find_jj_workspace_root(start: &Path) -> Option<PathBuf> {
    let current = if start.is_dir() {
        start.to_path_buf()
    } else {
        start.parent()?.to_path_buf()
    };
    current
        .ancestors()
        .find(|candidate| candidate.join(".jj").join("repo").is_file())
        .map(Path::to_path_buf)
}

fn resolve_repo_root_from_jj_workspace(workspace_root: &Path) -> Result<PathBuf> {
    let pointer_path = workspace_root.join(".jj").join("repo");
    let pointer = fs::read_to_string(&pointer_path)
        .with_context(|| format!("failed to read {}", pointer_path.display()))?;
    let pointer = pointer.trim();
    if pointer.is_empty() {
        bail!("{} has an empty .jj/repo pointer", workspace_root.display());
    }
    let jj_repo_dir = if Path::new(pointer).is_absolute() {
        PathBuf::from(pointer)
    } else {
        workspace_root.join(".jj").join(pointer)
    }
    .canonicalize()
    .with_context(|| {
        format!(
            "failed to resolve JJ repo pointer for {}",
            workspace_root.display()
        )
    })?;
    let repo_root = jj_repo_dir
        .parent()
        .and_then(Path::parent)
        .map(Path::to_path_buf)
        .ok_or_else(|| {

View on GitHub (pinned to a747e741ae)

Solutions

  1. Re-create the workspace with jj (`jj workspace add` or re-clone) so the pointer is regenerated
  2. Inspect .jj/repo and write the correct repo-store path if you know it
  3. Fall back to running against the git side if the workspace is colocated
Defensive patterns

Strategy: validation

Validate before calling

let p = workspace_root.join(".jj").join("repo");
let content = std::fs::read_to_string(&p)?;
if content.trim().is_empty() {
    anyhow::bail!("{} is empty; recreate the jj workspace", p.display());
}

Type guard

fn has_valid_jj_pointer(root: &Path) -> bool {
    std::fs::read_to_string(root.join(".jj").join("repo"))
        .map(|s| !s.trim().is_empty())
        .unwrap_or(false)
}

Try / catch

if let Err(e) = run_pr_preview(cmd) {
    if e.to_string().contains("empty .jj/repo pointer") {
        eprintln!("Recreate the jj workspace before previewing");
    }
}

Prevention

When it happens

Trigger: Running `f pr preview` in a jj workspace where `.jj/repo` exists but contains zero bytes or only whitespace.

Common situations: Interrupted `jj workspace add` / clone that left an empty pointer; manually created .jj scaffolding; filesystem truncation or a bad sync tool that emptied the file.

Related errors


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