{"record":{"id":"979e833b6be3691f","repo":"nikivdev/code","slug":"jj-failed","errorCode":null,"errorMessage":"jj {} failed: {}","messagePattern":"jj (.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/commit.rs","lineNumber":8463,"sourceCode":"    }\n    false\n}\n\nfn jj_run_in(repo_root: &Path, args: &[&str]) -> Result<()> {\n    let output = Command::new(jj_bin())\n        .current_dir(repo_root)\n        .args(args)\n        .output()\n        .with_context(|| format!(\"failed to run jj {}\", args.join(\" \")))?;\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        let stdout = String::from_utf8_lossy(&output.stdout);\n        let msg = if stderr.trim().is_empty() {\n            stdout.trim()\n        } else {\n            stderr.trim()\n        };\n        bail!(\"jj {} failed: {}\", args.join(\" \"), msg);\n    }\n    Ok(())\n}\n\nfn jj_capture_in(repo_root: &Path, args: &[&str]) -> Result<String> {\n    let output = Command::new(jj_bin())\n        .current_dir(repo_root)\n        .args(args)\n        .output()\n        .with_context(|| format!(\"failed to run jj {}\", args.join(\" \")))?;\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        let stdout = String::from_utf8_lossy(&output.stdout);\n        let msg = if stderr.trim().is_empty() {\n            stdout.trim()\n        } else {\n            stderr.trim()\n        };","sourceCodeStart":8445,"sourceCodeEnd":8481,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/commit.rs#L8445-L8481","documentation":"Generic failure wrapper for fire-and-forget jj commands (via `jj_run_in`). When the spawned `jj <args>` process exits non-zero, the function combines the command name with the captured stderr (falling back to stdout when stderr is empty) and bails with this formatted message. It surfaces jj's own diagnostics verbatim to the caller.","triggerScenarios":"Any call to the fire-and-forget jj helper where `output.status.success()` is false — e.g. `jj new`, `jj describe`, or `jj bookmark set` failing due to invalid arguments, unresolvable revisions, or workspace issues.","commonSituations":"Typo'd or unsupported jj subcommand/flag on older jj versions; referencing a revision that does not exist; jj workspace not initialized in the repo; authentication or git-backend errors surfaced through jj.","solutions":["Read the jj message appended after 'jj {} failed:' — it is jj's own diagnostic","Re-run the exact jj command manually in the repo root to reproduce","Check that the jj binary version supports the flags used","Ensure the workspace is valid (`jj st` succeeds) before retrying"],"exampleFix":"// before\nError: jj describe failed: Error: working copy is stale\n// after\n$ jj workspace update-stale  # or `jj st` to auto-update\n$ tool commit                 # retry the operation","handlingStrategy":"try-catch","validationCode":"let out = Command::new(\"jj\").args([\"st\"]).output()?;\nif !out.status.success() {\n    return Err(anyhow!(\"jj workspace not usable: {}\",\n        String::from_utf8_lossy(&out.stderr)));\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = result {\n    let msg = e.to_string();\n    if msg.contains(\"failed:\") {\n        eprintln!(\"jj command failed; rerun manually to debug: jj <subcommand>\");\n    }\n    return Err(e);\n}","preventionTips":["Sanity-check the workspace with `jj st` before automating jj commands","Verify jj version supports all flags used (e.g. `jj --version`)","Use `FLOW_JJ_BIN` to pin the intended jj binary in scripts","Log the exact args so failures can be reproduced manually"],"tags":["vcs","jj","process-exit","cli"],"backgroundTag":"cli-command-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}