bat icon indicating copy to clipboard operation
bat copied to clipboard

BAT_PAGER="builtin" && --help parsing causes panic

Open imsakg opened this issue 4 months ago • 7 comments

export BAT_PAGER="builtin"
alias -g -- --help='--help 2>&1 | bat --language=help --style=plain'
thread 'main' panicked at src/output.rs:212:65:ary/Caches/Homebrew/cargo_cache/registry/src/index.crates.io-1called `Result::unwrap()` on an `Err` value: Any { .. }

imsakg avatar Oct 20 '25 10:10 imsakg

The panic occurs in the Drop implementation for OutputType in src/output.rs. The problematic code is:

https://github.com/sharkdp/bat/blob/4e13c3eb5bd5e78de8cafb4b21f646b880216c2d/src/output.rs#L210-L214

char 65 would be the final .unwrap

https://github.com/sharkdp/bat/blob/4e13c3eb5bd5e78de8cafb4b21f646b880216c2d/src/output.rs#L19

  • The first one is safe as we checked is_some(), this takes the JoinHandle out of the Option
  • The second is the problematic one. JoinHandle<T>::join() returns a Result<T>, since T here is Result<()> then it returns Result<Result<()>>. This would be failing either from the spawned thread panicking in turn or the thread returning an Err result, not sure if it’s possible to say which from this? but I’d guess the latter

The thread is created like this

https://github.com/sharkdp/bat/blob/4e13c3eb5bd5e78de8cafb4b21f646b880216c2d/src/output.rs#L26-L31

The thread is running minus::dynamic_paging() (docs) which can return an error. If that function fails or panics, the join().unwrap() will panic during cleanup.

Indeed its docs say

Panics

This function will panic if another instance of minus is already running.

Errors

The function will return with an error if it encounters a error during paging.

…so still not sure which is causing it here.

If that could always potentially contain an Err then we shouldn’t be unwrapping it

Since we don’t actually use that result (we assign to _, drop never returns anything) I am wondering why we’re unwrapping it in the first place (or if we have to at all).

Could we just take, unwrap once, and join?

lmmx avatar Oct 20 '25 19:10 lmmx

Cannot repro this namely as my alias doesn't have a -g flag

@imsakg can you repro with any other style of calling it, e.g. by setting BAT_PAGER='builtin' before the call to bat like this

echo "hello" | BAT_PAGER='builtin' bat

It doesn't panic when I call it like this:

echo "hello" | BAT_PAGER='builtin' bat --language=help --style=plain

The info you gave above doesn't include the call you used that panicked, as the alias has bat wrapped in a string. More info would be helpful to debug

lmmx avatar Oct 20 '25 20:10 lmmx

I wonder if this has been fixed by https://github.com/sharkdp/bat/pull/3457 - perhaps you could confirm please @imsakg ? You can install or build from source for now. I plan to make a new release soon, but first I want to be sure as many bugs are squashed as possible.

keith-hall avatar Dec 01 '25 20:12 keith-hall

Panic when running cargo --help after setting BAT_PAGER=builtin (compiled from source, debug build)

Summary

After compiling bat from source (v0.26.0, Rust 1.90.0) in debug mode and adding the binary to my PATH, running cargo --help repeatedly triggers a panic originating from the minus crate (5.6.1). The crash occurs when BAT_PAGER=builtin is enabled.

Environment • bat version: v0.26.0 (compiled from source, debug build) • Rust version: 1.90.0 • OS: macOS • Install method: Local debug build (cargo build) • Binary path: /Users/msa/.builds/cargo/target/debug/bat

Environment variables:

export PATH="/Users/msa/.builds/cargo/target/debug:$PATH"
export BAT_PAGER="builtin"
alias -g -- --help='--help 2>&1 | bat --language=help --style=plain'

Steps to Reproduce 1. Clone repository 2. Build without --release:

cargo build

3.	Add debug build to PATH
4.	Set:

export BAT_PAGER="builtin"

5.	Run cargo --help repeatedly
6.	Run with backtrace to observe failure:

RUST_BACKTRACE=1 cargo --help

Observed Behavior

Initially, output is normal, but after a few runs: • Terminal prints corrupted sequences (35;61;20M) • Then panics inside minus initialization:

thread '' panicked at .../minus-5.6.1/src/core/init.rs:311:35: Static variable RUNMODE set to uninitialized.

thread '' panicked at .../minus-5.6.1/src/core/init.rs:197:28: called Result::unwrap() on an Err value: Any { .. }

thread 'main' panicked at src/output.rs:214:65: called Result::unwrap() on an Err value: Any { .. }

This suggests a race or improper global state setup within the builtin pager logic.

Expected Behavior

cargo --help should operate normally under repeated invocation without terminal corruption or runtime panic — even when using BAT_PAGER=builtin and a debug-compiled binary.

Additional Notes • Panic only happens with builtin pager enabled • No issues with default pager • Build completes fine; failure is runtime-only • Debug build makes reproducing the issue extremely consistent

imsakg avatar Dec 02 '25 13:12 imsakg

bat version: v0.26.0 (compiled from source, debug build)

just a side note, when building from source, it is generally better to refer to the commit hash you had checked out when compiling, otherwise it can be confusing.

keith-hall avatar Dec 02 '25 20:12 keith-hall

Sorry to call you out @academician, but I feel like you are our local minus expert and perhaps our best chance at fixing this - could you take a look when you get some spare time please?

keith-hall avatar Dec 02 '25 20:12 keith-hall

@keith-hall Hey, sorry I missed the ping - I'll take a look as soon as I can!

academician avatar Dec 04 '25 12:12 academician