{"record":{"id":"6ec2969e7ee6e4bd","repo":"GitoxideLabs/gitoxide","slug":"external-diff-exited-with-status","errorCode":null,"errorMessage":"external diff exited with {status}","messagePattern":"external diff exited with (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"gix-tix/src/lib.rs","lineNumber":6099,"sourceCode":"        for reference in &group.references {\n            let mut refspec = b\":\".to_vec();\n            refspec.extend_from_slice(reference.as_bstr());\n            command.arg(gix::path::from_bstr(refspec.as_bstr()).as_ref());\n        }\n        match command.status() {\n            Ok(status) if status.success() => outcome.deleted += group.references.len(),\n            Ok(status) => outcome.failures.push(format!(\"{} exited with {status}\", group.remote)),\n            Err(err) => outcome.failures.push(format!(\"{}: {err}\", group.remote)),\n        }\n    }\n    outcome\n}\n\nfn external_diff_status(status: ExitStatus) -> Result<()> {\n    if status.success() || status.code() == Some(1) {\n        Ok(())\n    } else {\n        anyhow::bail!(\"external diff exited with {status}\")\n    }\n}\n\nfn pager_write_result(result: io::Result<()>) -> Result<()> {\n    match result {\n        Err(err) if err.kind() == io::ErrorKind::BrokenPipe => Ok(()),\n        result => result.context(\"could not write diff to pager\"),\n    }\n}\n\nfn pager_status(status: ExitStatus) -> Result<()> {\n    if status.success() {\n        Ok(())\n    } else {\n        anyhow::bail!(\"diff pager exited with {status}\")\n    }\n}\n","sourceCodeStart":6081,"sourceCodeEnd":6117,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/lib.rs#L6081-L6117","documentation":"The configured external diff program (diff.external / GIT_EXTERNAL_DIFF) exited with a status other than 0 or 1. Exit 1 is tolerated because diff tools conventionally use it to mean 'files differ'; anything else indicates the tool itself failed.","triggerScenarios":"Running a file diff through the external diff command, which exits with e.g. 2 (usage error), 127 (command shell issue), 127/126, or a crash exit code.","commonSituations":"Misconfigured diff.external pointing to a broken script; external tool missing dependencies; tool crashing on binary/large files; wrong argument conventions.","solutions":["Run the external diff command manually with the same arguments to see its real error.","Fix or replace diff.external in config (or unset GIT_EXTERNAL_DIFF) and re-run.","Make your custom diff tool return 0 (same) or 1 (differ) and reserve other codes for real failures.","If the tool crashes on this input, test it on the specific files involved."],"exampleFix":"// before\n#!/bin/sh\ncompare \"$@\"  # exit 2 on usage errors\n// after\n#!/bin/sh\ncompare \"$@\" || exit 1  # map failures to diff-style exit codes","handlingStrategy":"validation","validationCode":"let cmd = repo.config_snapshot().trusted_program(gix::config::tree::Diff::EXTERNAL)?;\n// test it: run cmd with two temp files and require exit 0 or 1","typeGuard":null,"tryCatchPattern":"match show_external_diff(...) {\n    Err(err) if err.to_string().starts_with(\"external diff exited with\") => {\n        eprintln!(\"{}; falling back to built-in diff\", err);\n    }\n    other => other?,\n}","preventionTips":["Test the external diff tool on sample files before configuring it.","Ensure the tool only exits 0 or 1 for normal operation.","Keep diff.external simple; avoid scripts with unhandled usage errors."],"tags":["diff","external-tool","subprocess","exit-code"],"backgroundTag":"external-tool-exit-code","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}