BurntSushi/ripgrep · error

preprocessor command could not start: '{cmd:?}': {err}

Error message

preprocessor command could not start: '{cmd:?}': {err}

What it means

In SearchWorker::search_preprocessor, the configured preprocessor command is spawned via command_builder.build(&mut cmd). If spawning fails (binary not found, not executable, out of resources), the error is wrapped as format!("preprocessor command could not start: '{cmd:?}': {err}"). It distinguishes a spawn failure from a search failure of an already-running preprocessor.

Source

Thrown at crates/core/search.rs:307

            return true;
        }
        !self.config.preprocessor_globs.matched(path, false).is_ignore()
    }

    /// Search the given file path by first asking the preprocessor for the
    /// data to search instead of opening the path directly.
    fn search_preprocessor(
        &mut self,
        path: &Path,
    ) -> io::Result<SearchResult> {
        use std::{fs::File, process::Stdio};

        let bin = self.config.preprocessor.as_ref().unwrap();
        let mut cmd = std::process::Command::new(bin);
        cmd.arg(path).stdin(Stdio::from(File::open(path)?));

        let mut rdr = self.command_builder.build(&mut cmd).map_err(|err| {
            io::Error::new(
                io::ErrorKind::Other,
                format!(
                    "preprocessor command could not start: '{cmd:?}': {err}",
                ),
            )
        })?;
        let result = self.search_reader(path, &mut rdr).map_err(|err| {
            io::Error::new(
                io::ErrorKind::Other,
                format!("preprocessor command failed: '{cmd:?}': {err}"),
            )
        });
        let close_result = rdr.close();
        let search_result = result?;
        close_result?;
        Ok(search_result)
    }

View on GitHub (pinned to 3fce3b5bb0)

Solutions

  1. Confirm the preprocessor binary exists, is executable, and is on PATH (use an absolute path to be safe).
  2. chmod +x the script, or invoke an interpreter explicitly (e.g. /usr/bin/python3 script.py).
  3. Use --pre-glob to restrict preprocessing and verify the binary works standalone on a sample file first.

Example fix

// before
let mut b = SearchWorkerBuilder::new();
b.preprocessor(Path::new("mypp")); // not on PATH -> could not start

// after
b.preprocessor(Path::new("/usr/local/bin/mypp"));
Defensive patterns

Strategy: validation

Validate before calling

fn preprocessor_runnable(p: &std::path::Path) -> bool {
    use std::path::Path;
    fn on_path(name: &str) -> bool {
        std::env::var_os("PATH").map(|paths| {
            std::env::split_paths(&paths).any(|dir| dir.join(name).exists())
        }).unwrap_or(false)
    }
    p.is_absolute() && p.exists() || on_path(p.to_string_lossy().as_ref())
}

Try / catch

if let Err(e) = run_search_with_preprocessor(path) {
    eprintln!("{e}"); // could not start
    return;
}

Prevention

When it happens

Trigger: Configuring SearchWorkerBuilder.preprocessor(path) to a program that does not exist, lacks execute permission, or cannot be forked; PATH does not contain the preprocessor binary.

Common situations: rg --pre some-script where some-script is missing or not on PATH; a wrapper script without +x; a CI container missing the preprocessor dependency; a typo in the --pre argument.

Related errors


AI-assisted analysis of BurntSushi/ripgrep@3fce3b5bb0 (2026-08-06). Data as JSON: /data/errors/4af73dba88a9338b.json. Report an issue: GitHub.