sharkdp/fd · error · anyhow::Error

Malformed exclude pattern

Error message

Malformed exclude pattern: {}

What it means

build_overrides (walk.rs:330) feeds each --exclude pattern into ignore::OverrideBuilder::add; if a pattern is syntactically invalid as a glob it returns Err, which fd wraps at walk.rs:339 as 'Malformed exclude pattern'. This is per-pattern: the first bad glob aborts with its underlying message.

Solutions

  1. Correct the glob: balance brackets/braces, e.g. `fd --exclude '[abc]'`.
  2. Remember --exclude uses gitignore/glob syntax, not regex.
  3. Test the glob with `fd --exclude '<pattern>' --max-depth 0 .` in a scratch dir to iterate quickly.

Example fix

# before
fd --exclude '[abc' .

# after
fd --exclude '[abc]' .
Defensive patterns

Strategy: validation

Validate before calling

validate_glob() {
  # reject unterminated classes/braces cheaply
  case "$1" in
    *'['*[*]*) : ;;
  esac
  # best effort: rely on a glob-aware tool, or just try fd with --max-depth 0
  fd --exclude "$1" --max-depth 0 . >/dev/null 2>&1 || echo "bad glob: $1" >&2
}

Prevention

When it happens

Trigger: Passing `fd --exclude '[abc'` (unterminated class), `fd --exclude 'a{b,c'` (unbalanced brace), or any glob the ignore crate's parser rejects.

Common situations: Typos in glob patterns; using regex syntax where glob is expected; copy-pasting patterns from tools with different glob dialects.

Understand the failure class

Related errors


AI-assisted analysis of sharkdp/fd@ee20f426dd (2026-08-09). Data as JSON: /api/errors/5c6d694adec5627e. Report an issue: GitHub.

Appendix: source

Thrown at src/walk.rs:339

        Self {
            patterns,
            config,
            quit_flag,
            interrupt_flag,
        }
    }

    fn build_overrides(&self, paths: &[PathBuf]) -> Result<Override> {
        let first_path = &paths[0];
        let config = &self.config;

        let mut builder = OverrideBuilder::new(first_path);

        for pattern in &config.exclude_patterns {
            builder
                .add(pattern)
                .map_err(|e| anyhow!("Malformed exclude pattern: {}", e))?;
        }

        builder
            .build()
            .map_err(|_| anyhow!("Mismatch in exclude patterns"))
    }

    fn build_walker(&self, paths: &[PathBuf]) -> Result<WalkParallel> {
        let first_path = &paths[0];
        let config = &self.config;
        let overrides = self.build_overrides(paths)?;

        let mut builder = WalkBuilder::new(first_path);
        builder
            .hidden(config.ignore_hidden)
            .ignore(config.read_fdignore)
            .parents(config.read_parent_ignore && (config.read_fdignore || config.read_vcsignore))
            .git_ignore(config.read_vcsignore)

View on GitHub (pinned to ee20f426dd)