GitoxideLabs/gitoxide · error · anyhow::Error

diff pager exited with

Error message

diff pager exited with {status}

What it means

The pager process used to display diff output (e.g. configured core.pager or the built-in pager) exited with a non-zero status. A non-successful pager exit usually means the pager crashed or was killed, not that the diff itself failed.

Solutions

  1. Check which pager is configured (core.pager, GIT_PAGER, PAGER) and test it standalone.
  2. Reset to a known-good pager: git config --unset core.pager or use `less`.
  3. If the pager was killed (signal), check memory/ulimits and shell pipeline behavior.
  4. Bypass the pager (e.g. --no-pager equivalent / pipe to file) to isolate the issue.

Example fix

// before
GIT_PAGER='mypager.sh' gix diff
// after
GIT_PAGER='less -FRX' gix diff
Defensive patterns

Strategy: try-catch

Validate before calling

let pager = std::env::var("GIT_PAGER").or_else(|_| std::env::var("PAGER")).unwrap_or_default();
if !pager.is_empty() && which::which(pager.split_whitespace().next().unwrap_or_default()).is_err() { /* bad pager */ }

Try / catch

match show_diff_in_pager(...) {
    Err(err) if err.to_string().starts_with("diff pager exited with") => {
        eprintln!("pager failed; printing to stdout instead");
    }
    other => other?,
}

Prevention

When it happens

Trigger: After streaming the diff into the pager and waiting, pager_status() observes ExitStatus that is not success — pager killed by a signal, pager binary missing its dependencies, or pager exiting with an error.

Common situations: less exiting via signal (e.g. SIGKILL/OOM); a custom core.pager script failing; PAGER env var pointing at a non-pager command that returns non-zero.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/464a4b1b8b20dba0. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/lib.rs:6114

    if status.success() || status.code() == Some(1) {
        Ok(())
    } else {
        anyhow::bail!("external diff exited with {status}")
    }
}

fn pager_write_result(result: io::Result<()>) -> Result<()> {
    match result {
        Err(err) if err.kind() == io::ErrorKind::BrokenPipe => Ok(()),
        result => result.context("could not write diff to pager"),
    }
}

fn pager_status(status: ExitStatus) -> Result<()> {
    if status.success() {
        Ok(())
    } else {
        anyhow::bail!("diff pager exited with {status}")
    }
}

fn pager_needs_acknowledgement(elapsed: Duration) -> bool {
    elapsed <= IMMEDIATE_PAGER_EXIT
}

fn show_builtin_diff(terminal: &mut ratatui::DefaultTerminal, diff: &BuiltInDiff) -> Result<bool> {
    let mut offset = 0usize;
    let mut horizontal_offset = 0usize;
    let mut focused = true;
    loop {
        let size = terminal.size().context("could not determine diff viewport")?;
        let page = usize::from(size.height.saturating_sub(2)).max(1);
        let max = diff.display_line_count().saturating_sub(page);
        let horizontal_page = usize::from(size.width).max(1);
        let horizontal_max = diff.max_width.saturating_sub(horizontal_page);
        offset = offset.min(max);

View on GitHub (pinned to e73179060b)