Skip to content

[Bug]: multi_grep drops positive constraints and degrades OR results #738

Description

@Kh05ifr4nD

Which fff frontend?

MCP server (fff-mcp)

has logs

Not applicable: this is deterministic incorrect output without a server error.

Description

Summary

multi_grep does not apply positive file constraints. It can therefore return matches outside the requested scope. Its documented OR behavior also collapses when any requested pattern has no match; the plain-grep fallback masks the zero result but returns only the first successful pattern.

Reproduced on fff-mcp 0.10.1; current main contains the same code path. I found no existing issue covering this behavior.

Sanitized reproduction

Use any indexed repository containing:

scope-a/one.txt   alpha
scope-a/two.txt   beta
scope-b/three.txt alpha

Positive directory constraint:

{
  "patterns": ["alpha"],
  "constraints": "scope-a/"
}

Expected: only scope-a/one.txt.

Actual: matches from both scopes. The same occurs with a positive glob or exact-file constraint. A negative constraint is applied correctly. Ordinary grep with the equivalent inline query (scope-a/ alpha) is scoped correctly.

OR control:

{
  "patterns": ["alpha", "definitely_missing_token"],
  "constraints": "scope-a/"
}

Expected: the alpha match, because patterns is documented as OR.

Actual: the core multi-pattern search returns zero, then the server reports a plain-grep fallback for one pattern. Because the fallback returns after the first successful pattern, it cannot preserve the union for a larger pattern set.

Root cause

In crates/fff-mcp/src/server.rs, multi_grep_inner parses the standalone constraints string with AiGrepConfig, then passes only parsed_constraints.constraints to the picker. A lone positive path/glob is retained as grep text rather than classified as a constraint, leaving the constraint slice empty. The fallback reconstructs an inline query correctly, but exits after the first successful pattern.

Impact

This is a silent scope violation: callers can believe a directory, glob, or exact-file restriction was enforced when it was not. Multi-pattern results can also be incomplete while appearing successful through fallback output.

Suggested regression tests

  • Positive directory constraint
  • Positive extension/glob constraint
  • Positive exact-file constraint
  • Negative constraint
  • OR with one matching and one missing pattern
  • OR with multiple matching patterns plus one missing pattern

A useful invariant is: multi_grep(patterns, constraint) must equal the deduplicated union of individually scoped grep calls for the same patterns and constraint.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions