AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

`StateFileSearchMiddleware`: `Grep_search` And `Glob_search` Return No Results When `Path` Ends In A Slash

When the model passes a directory path with a trailing slash (e.g., `/app/`), both `grep_search` and `glob_search` in `StateFileSearchMiddleware` return "No matches found" / "No files found". This happens because the handlers construct a prefix check using `base_path + "/"`, and if `base_path` already ends with `/`, a doubled separator is produced, which matches no file paths. The issue was introduced for `grep_search` by PR #39681 and has always existed in `glob_search`.

highConfidence 95%LangchainAffected V1.6.1

Origin Analysis

The base path is only normalized by adding a leading slash if missing, but trailing slashes are not stripped. The subsequent prefix filter checks `file_path.startswith(base_path + "/")`. For a path like `/app/`, `base_path` becomes `/app/` and `base_path + "/"` becomes `/app//`, which never matches actual file paths such as `/app/config.txt`.
```python from langchain_anthropic.middleware.file_search import StateFileSearchMiddleware middleware = StateFileSearchMiddleware() state = { middleware.state_key: { "/app/config.txt": {"content": ["service=web"], "modified_at": 1}, } } for path in ("/app", "/app/"): grep = middleware._handle_grep_search( pattern="service", path=path, include=None, output_mode="files_with_matches", state=state, ) glob = middleware._handle_glob_search(pattern="*.txt", path=path, state=state) print(f"path={path!r:8} grep -> {grep!r:20} glob -> {glob!r}") ``` Expected: both `/app` and `/app/` return the same files. Actual: `/app/` returns no matches / no files.

Fixing Code Block

Edge Case Audit

Edge cases to test: path="/" (root) must still work and match all absolute paths; path="" will normalize to "/" and may unintentionally match the entire filesystem if an empty string is ever passed. The fix assumes Unix-style absolute paths; Windows backslashes are not handled. If rollback is needed, simply revert to the original `base_path = path if path.startswith("/") else "/" + path` in both methods. No concurrency or thread-safety issues expected because the middleware reads immutable state during a request.

Ecosystem Topology