nikivdev/code · error

jj {} failed

Error message

jj {} failed

What it means

jj_run_in executes a jj subcommand in the repo root, streaming its stderr; if the process exits non-zero it bails with the full argument list. The actual jj error text is already printed to stderr lines above the bail message.

Source

Thrown at src/ext.rs:381

fn jj_run_in(repo_root: &Path, args: &[&str]) -> Result<()> {
    let output = Command::new("jj")
        .current_dir(repo_root)
        .args(args)
        .output()
        .with_context(|| format!("failed to run jj {}", args.join(" ")))?;
    let stdout = String::from_utf8_lossy(&output.stdout);
    if !stdout.trim().is_empty() {
        print!("{}", stdout);
    }
    let stderr = String::from_utf8_lossy(&output.stderr);
    for line in stderr.lines() {
        if line.contains("Refused to snapshot") {
            continue;
        }
        eprintln!("{}", line);
    }
    if !output.status.success() {
        bail!("jj {} failed", args.join(" "));
    }
    Ok(())
}

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

fn git_capture_in(repo_root: &Path, args: &[&str]) -> Result<String> {
    let output = Command::new("git")

View on GitHub (pinned to a747e741ae)

Solutions

  1. Read the stderr lines printed just before the error to see jj's own message, then fix that condition.
  2. Re-run the same jj command manually in the source repo to reproduce and diagnose.
  3. Resolve working-copy problems (conflicts, locks) in the source workspace and retry the import.

Example fix

// before: opaque failure
// error: jj workspace add ... failed
// after (shell): reproduce for the real error
cd <source> && jj workspace add --help  # or re-run the failing command verbatim
Defensive patterns

Strategy: retry

Validate before calling

let probe = std::process::Command::new("jj")
    .args(["--version"])
    .output()
    .map(|o| o.status.success())
    .unwrap_or(false);
if !probe { return Err(anyhow!("jj is unavailable; install jujutsu first")); }

Try / catch

for attempt in 0..2 {
    match import_external_path(source) {
        Err(e) if e.to_string().starts_with("jj ") && attempt == 0 => {
            eprintln!("jj failed ({e}); inspect stderr above, fixing state and retrying");
            continue;
        }
        r => { r?; break; }
    }
}

Prevention

When it happens

Trigger: Any jj invocation from prepare_source_workspace failing: workspace add refused, snapshot refused due to a dirty/locked working copy, invalid args, or jj missing/crashing.

Common situations: Source repo with conflicts or an inconsistent working copy; incompatible jj version; running while another jj process holds a lock.

Related errors


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