imsnif/bandwhich · error

Failed to get stdout: if you are trying to pipe 'bandwhich'…

Error message

Failed to get stdout: if you are trying to pipe 'bandwhich' you should use the --raw flag

What it means

bandwhich's normal (non --raw) mode requires a TTY so it can put the terminal into raw mode for its TUI. When `terminal::enable_raw_mode()` fails (typically because stdout is a pipe, not a terminal), it aborts with this message pointing the user to the --raw flag.

Solutions

  1. Add the --raw flag when piping: `bandwhich --raw | your-consumer`
  2. Run bandwhich directly in an interactive terminal when you want the TUI
  3. If invoking programmatically, check `isatty(stdout)` first and pass --raw when false

Example fix

// before
bandwhich | grep chromecast
// after
bandwhich --raw | grep chromecast
Defensive patterns

Strategy: validation

Validate before calling

use std::io::IsTerminal;
let interactive = std::io::stdout().is_terminal();
let needs_raw_flag = !interactive; // pass --raw when output is piped
if needs_raw_flag { args.push("--raw"); }

Try / catch

// shell wrapper
if [ -t 1 ]; then bandwhich "$@"; else bandwhich --raw "$@"; fi

Prevention

When it happens

Trigger: Running bandwhich and piping/redirecting its output (e.g. `bandwhich | grep ...`, `bandwhich > out.txt`) without `--raw`, so `enable_raw_mode()` returns Err.

Common situations: Users piping bandwhich output into another process or a file, running it in CI or scripts, capturing output in an IDE terminal without a pty.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of imsnif/bandwhich@1899870cea (2026-09-08). Data as JSON: /api/errors/004c2b3a99e5a21a. Report an issue: GitHub.

Appendix: source

Thrown at src/main.rs:63

    if let Some(ref log_path) = opts.log_to {
        let log_file = File::options()
            .write(true)
            .create_new(true)
            .open(log_path)?;
        WriteLogger::init(
            opts.verbosity.log_level_filter(),
            Default::default(),
            log_file,
        )?;
    }

    let os_input = os::get_input(opts.interface.as_deref(), !opts.no_resolve, opts.dns_server)?;
    if opts.raw {
        let terminal_backend = RawTerminalBackend {};
        start(terminal_backend, os_input, opts);
    } else {
        let Ok(()) = terminal::enable_raw_mode() else {
            bail!(
                "Failed to get stdout: if you are trying to pipe 'bandwhich' you should use the --raw flag"
            )
        };

        let mut stdout = std::io::stdout();
        // Ignore enteralternatescreen error
        let _ = crossterm::execute!(&mut stdout, terminal::EnterAlternateScreen);
        let terminal_backend = CrosstermBackend::new(stdout);
        start(terminal_backend, os_input, opts);

        // Ensure terminal is restored after exit (handles SIGINT case).
        // These operations are idempotent, so safe to call even if 'q' already cleaned up.
        let _ = terminal::disable_raw_mode();
        let _ = crossterm::execute!(std::io::stdout(), terminal::LeaveAlternateScreen);
    }
    Ok(())
}

View on GitHub (pinned to 1899870cea)