sinelaw/fresh · warning · io::Error (InvalidInput)

(regex compile error)

Error message

(regex compile error)

What it means

Project search fails when the search pattern cannot be compiled as a regex (regex::bytes::Regex::new returns Err). The library wraps the regex error as InvalidInput; this is a user-supplied pattern problem, not an internal bug. Multi-line patterns additionally get a (?s) prefix before compiling.

Solutions

  1. Fix the regex syntax (balance groups, escape metacharacters with backslash).
  2. Enable fixed_string option to search literally without regex interpretation.
  3. Test the pattern in a regex validator (rust regex crate flavor) before searching.

Example fix

// before
SearchOptions { pattern: "foo(bar".into(), fixed_string: false, .. }
// after
SearchOptions { pattern: "foo\\(bar".into(), fixed_string: false, .. }
// or
SearchOptions { pattern: "foo(bar".into(), fixed_string: true, .. }
Defensive patterns

Strategy: validation

Validate before calling

if !opts.fixed_string {
    if let Err(e) = regex::bytes::Regex::new(&opts.pattern) {
        eprintln!("invalid search pattern: {e}");
        return;
    }
}

Try / catch

match run_search(pattern, opts) {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => {
    // surface the regex error to the user and offer fixed-string mode
    prompt_fixed_string_fallback(pattern)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running search with fixed_string disabled and a pattern containing invalid regex syntax (unbalanced parenthesis, bad quantifier like `*foo`, invalid escape `\q`), including multi-line patterns routed through the (?s) wrapper.

Common situations: Users typing globs/wildcard-style patterns expecting shell semantics; patterns copied with unescaped special characters; searching for literal text containing regex metacharacters without fixed-string mode.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/94fb7eabe22aacf7. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor-core/src/model/filesystem.rs:905

    };
    let re_pattern = if opts.whole_word {
        format!(r"\b{}\b", re_pattern)
    } else {
        re_pattern
    };
    let re_pattern = if opts.case_sensitive {
        re_pattern
    } else {
        format!("(?i){}", re_pattern)
    };
    // Multi-line regex patterns get (?s) so `.` matches newlines.
    let re_pattern = if !opts.fixed_string && pattern.contains('\n') {
        format!("(?s){}", re_pattern)
    } else {
        re_pattern
    };
    regex::bytes::Regex::new(&re_pattern)
        .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))
}

/// Maximum per-file size for unbounded project-wide search.  Files larger
/// than this are treated as binary and skipped: searching multi-gigabyte
/// archives, model weights, or audio files would otherwise lock up the
/// editor for minutes (issue #1342).  Source files virtually never exceed
/// this limit; users wanting to search huge text logs should open them
/// directly so hybrid buffer search applies.
pub const MAX_PROJECT_SEARCH_FILE_SIZE: u64 = 10 * 1024 * 1024;

/// Filename extensions that always represent binary content for project
/// search.  Files matching this list are skipped before any I/O — no
/// `stat`, no header read — which both avoids waste on the obvious cases
/// and removes the dependency on heuristic content detection for formats
/// whose first 8 KB can occasionally look text-like.
///
/// Kept as a sorted ASCII-lowercase list and matched case-insensitively
/// via `eq_ignore_ascii_case` (no allocation per file).

View on GitHub (pinned to 67894ca546)