nikivdev/code · error

jj {} failed: {}

Error message

jj {} failed: {}

What it means

jj_read_in runs `jj --at-op=@ --ignore-working-copy <args>` for lock-free reads; on non-zero exit it raises 'jj <args> failed: <stderr>' with git-style stderr inclusion. Because --ignore-working-copy is passed, failures usually come from the repository state rather than the working copy.

Source

Thrown at src/jj.rs:3418

        .output()
        .with_context(|| format!("failed to run git {}", args.join(" ")))?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        bail!("git {} failed: {}", args.join(" "), stderr.trim());
    }
    Ok(String::from_utf8_lossy(&output.stdout).to_string())
}

fn jj_read_in(repo_root: &Path, args: &[&str]) -> Result<String> {
    let output = Command::new("jj")
        .current_dir(repo_root)
        .args(["--at-op=@", "--ignore-working-copy"])
        .args(args)
        .output()
        .with_context(|| format!("failed to run jj {}", args.join(" ")))?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        bail!("jj {} failed: {}", args.join(" "), stderr.trim());
    }
    Ok(String::from_utf8_lossy(&output.stdout).to_string())
}

fn jj_overview_cache() -> &'static Mutex<HashMap<JjOverviewCacheKey, CachedJjOverview>> {
    static CACHE: OnceLock<Mutex<HashMap<JjOverviewCacheKey, CachedJjOverview>>> = OnceLock::new();
    CACHE.get_or_init(|| Mutex::new(HashMap::new()))
}

fn cached_overview(cache_key: &JjOverviewCacheKey) -> Option<JjWorkflowOverview> {
    let now = now_unix_secs();
    let cache = jj_overview_cache().lock().ok()?;
    let entry = cache.get(cache_key)?;
    if now.saturating_sub(entry.stored_at_unix) > JJ_OVERVIEW_CACHE_TTL_SECS {
        return None;
    }
    Some(entry.snapshot.clone())
}

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the stderr included in the error for jj's specific complaint.
  2. Resolve repository conflicts (`jj resolve`, then `jj rebase`) so read queries succeed.
  3. Fix the revset/change id argument; test it directly with `jj log -r <revset>`.

Example fix

// before
flow overview  # jj_read_in fails on conflicted repo
// after
jj resolve --list
jj resolve --tool meld <file>
flow overview
Defensive patterns

Strategy: try-catch

Validate before calling

// shell: reject conflicted repos before read commands
jj log -r 'conflicts()' -n 1 2>/dev/null | grep -q . && { echo "repo has conflicts" >&2; exit 1; } || true

Try / catch

match flow_overview() {
  Err(e) if e.contains("jj ") && e.contains("failed: ") => {
    eprintln("jj read failed — resolve conflicts or fix revset, then retry");
    Err(e)
  }
  other => other,
}

Prevention

When it happens

Trigger: Read commands routed through jj_read_in exit non-zero — most often 'repository has conflicts' or operations requiring a snapshot running with --ignore-working-copy, or an invalid revset argument.

Common situations: Conflicted commits in the repo making read revsets fail; passing a revset that matches nothing or is syntactically invalid; running against a repo still being mutated by another jj process.

Related errors


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