bensadeh/tailspin · error · anyhow::Error

--exec command failed

Error message

--exec command failed ({status})

What it means

This error is thrown when the external process spawned via --exec exits with a non-zero status after the reader has consumed all of its output. The library waits on the child process and requires a successful exit; any non-zero exit code means the command itself failed mid-stream, so the read pipeline reports the failure instead of returning partial data as success.

Solutions

  1. Run the --exec command manually and check its exit code to see why it fails
  2. Fix the bug or typo in the command so it exits 0 on success
  3. If non-zero exits are expected/harmless, wrap the command so it exits 0, e.g. append '|| true' in a shell wrapper
  4. Check whether the command was killed by a signal (status reported in the message) and address resource limits (OOM, disk)

Example fix

// before
myapp --exec "cat data.txt; grep missing-pattern"
// after
myapp --exec "cat data.txt; grep missing-pattern || true"
Defensive patterns

Strategy: try-catch

Validate before calling

mycmd; echo "exit=$?"  # run the --exec command standalone first and confirm exit code 0

Try / catch

match reader.next() {
    Err(e) if e.to_string().contains("--exec command failed") => {
        eprintln!("underlying command exited nonzero: {e}");
        // inspect/repair the command, or fall back to reading from a file
    }
    Err(e) => return Err(e),
    Ok(ev) => { /* handle event */ }
}

Prevention

When it happens

Trigger: Running a pager session where the --exec command finishes but exits with a non-zero exit status (e.g. the command crashes, is killed by a signal, or calls exit(1)). Specifically triggered in CommandReader::next when read_batch returns Eof and child.wait() yields a failing ExitStatus.

Common situations: The user passes a shell command with a typo that fails late in execution; the command hits an internal error after producing some output; the command is terminated by SIGSEGV/SIGKILL; a script under --exec ends with a failing subcommand.

Related errors


AI-assisted analysis of bensadeh/tailspin@8ecaa9a8a1 (2026-09-13). Data as JSON: /api/errors/a61a6b8a92bfb1af. Report an issue: GitHub.

Appendix: source

Thrown at src/io/reader/command.rs:34

    pub fn new(command: String) -> Result<CommandReader> {
        spawn_command(command)
    }

    pub fn child(&self) -> Arc<SharedChild> {
        self.child.clone()
    }

    pub fn next(&mut self) -> Result<StreamEvent> {
        if !self.initial_read_complete_sent {
            self.initial_read_complete_sent = true;

            return Ok(StreamEvent::InitialReadComplete);
        }

        let event = match read_batch(&mut self.reader)? {
            ReadResult::Eof => {
                let status = self.child.wait()?;
                ensure!(status.success(), "--exec command failed ({status})");
                StreamEvent::Ended
            }
            ReadResult::Batch(batch) => StreamEvent::Lines(batch),
        };

        Ok(event)
    }
}

#[cfg(not(windows))]
fn spawn_command(command: String) -> Result<CommandReader> {
    use crate::io::reader::line_batcher::BUF_READER_CAPACITY;
    use anyhow::Context;
    use std::process::{Command, Stdio};

    let trap_command = format!("trap '' INT; {command}");

    let mut sh = Command::new("sh");

View on GitHub (pinned to 8ecaa9a8a1)