sharkdp/fd · error · anyhow::Error

Malformed exclude pattern: {}

Error message

Malformed exclude pattern: {}

What it means

Thrown by WorkerState::build_overrides in src/walk.rs:339 when OverrideBuilder::add(pattern) returns an error for one of the --exclude patterns. The ignore crate's glob parser rejected the pattern — typically an unbalanced character class, bad '{' brace expansion, or a glob token it cannot compile.

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 41532d114e)

Solutions

  1. Balance brackets/braces: 'fd --exclude "[abc]"' or 'fd --exclude "{a,b}"'.
  2. Remember --exclude takes a glob, not a regex — use '*'/'?' for wildcards.
  3. If you need a regex filter, post-process fd's output instead of using --exclude.

Example fix

// before
fd --exclude '[unclosed'

// after
fd --exclude '[abc]'
Defensive patterns

Strategy: validation

Validate before calling

# rough glob sanity check: balanced [] and {}
bal() { printf '%s' "$1" | awk '{o=gsub(/\[/,"["); c=gsub(/\]/,"]"); ob=gsub(/\{/,"{"); cb=gsub(/\}/,"}"); exit !(o==c && ob==cb)}'; }
for p in "${EXCLUDES[@]}"; do bal "$p" || { echo "bad exclude glob: $p" >&2; exit 1; }; done
fd "${EXCLUDES[@]/#/--exclude }" "$PAT"

Type guard

use ignore::overrides::OverrideBuilder;
fn exclude_glob_is_valid(base: &str, pat: &str) -> bool {
    OverrideBuilder::new(base).add(pat).is_ok()
}

Prevention

When it happens

Trigger: Running 'fd --exclude "[unclosed"', 'fd --exclude "{a,b"' (unbalanced brace), or any exclude glob the ignore crate won't accept.

Common situations: Copy-pasting a regex into --exclude (which wants a glob); typos in brace expansion; nested brackets from gitignore syntax.

Related errors


AI-assisted analysis of sharkdp/fd@41532d114e (2026-08-06). Data as JSON: /data/errors/5c6d694adec5627e.json. Report an issue: GitHub.