Hmbown/CodeWhale · error

search root does not exist: {}

Error message

search root does not exist: {}

What it means

`search_files` (crates/tui/src/eval.rs:622) refuses to build a walker when `root.exists()` is false. The check runs before regex compilation, so a bad root surfaces as a path problem rather than a pattern problem.

Source

Thrown at crates/tui/src/eval.rs:622

fn read_workspace_file(path: &Path) -> Result<String> {
    fs::read_to_string(path).with_context(|| format!("failed to read {}", path.display()))
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct SearchMatch {
    path: PathBuf,
    line: usize,
    content: String,
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct SearchResult {
    matches: Vec<SearchMatch>,
}

fn search_files(root: &Path, pattern: &str) -> Result<SearchResult> {
    if !root.exists() {
        return Err(anyhow!("search root does not exist: {}", root.display()));
    }

    let regex = Regex::new(pattern).context("failed to compile search regex")?;
    let mut matches = Vec::new();

    let walker = WalkBuilder::new(root)
        .hidden(false)
        .git_ignore(false)
        .git_global(false)
        .git_exclude(false)
        .build();

    for entry in walker {
        let entry = entry.with_context(|| format!("failed to walk {}", root.display()))?;
        if !entry.file_type().is_some_and(|t| t.is_file()) {
            continue;
        }

View on GitHub (pinned to 8880682c63)

Solutions

  1. Create the directory or correct the root path passed to the search
  2. Guard callers with `root.try_exists()` before searching
  3. Log the resolved absolute root before invoking the search

Example fix

// before
let results = search_files(&root, pattern)?;
// after
anyhow::ensure!(root.is_dir(), "missing search root {}", root.display());
let results = search_files(&root, pattern)?;
Defensive patterns

Strategy: validation

Validate before calling

match root.try_exists() {
    Ok(true) => {}
    Ok(false) => std::fs::create_dir_all(&root)?,
    Err(err) => return Err(err.into()),
}

Type guard

fn searchable_root(root: &std::path::Path) -> bool {
    root.is_dir()
}

Prevention

When it happens

Trigger: A Grep-style eval tool call passes a root directory that was never created, was deleted mid-run, or is mistyped (an absolute path resolved against the wrong cwd, or a path built from an empty variable).

Common situations: Root computed from an empty config field or env var; workspace cleaned between steps; case mismatch on a case-sensitive filesystem.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/ca626891a58090f1. Report an issue: GitHub.