{"record":{"id":"ea7b9309fb40d3b3","repo":"langchain-ai/deepagents","slug":"notimplementederror-raised-by-abstract-grep-bac","errorCode":null,"errorMessage":"NotImplementedError raised by abstract `grep` (backend does not implement `grep`)","messagePattern":"NotImplementedError raised by abstract `grep` \\(backend does not implement `grep`\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/protocol.py","lineNumber":556,"sourceCode":"                matches are returned; if more exist the search stops and the\n                result is flagged with `GrepResult.truncated=True`. Exactly\n                `max_count` matches with none dropped is reported complete\n                (`truncated=False`). Interpreted as a total cap, not a per-file\n                cap.\n\n        Examples:\n            - `'*.py'` - only search Python files\n            - `'**/*.txt'` - search all `.txt` files recursively\n            - `'src/**/*.js'` - search JS files under src/\n            - `'test[0-9].txt'` - search `test0.txt`, `test1.txt`, etc.\n\n        Returns:\n            `GrepResult` with matches or error.\n\n        Raises:\n            NotImplementedError: If the backend does not implement `grep`.\n        \"\"\"\n        raise NotImplementedError\n\n    async def agrep(\n        self,\n        pattern: str,\n        path: str | None = None,\n        glob: str | None = None,\n        *,\n        max_count: int | None = None,\n    ) -> \"GrepResult\":\n        \"\"\"Async version of `grep`.\n\n        Wraps the sync call with an async timeout as a safety net. The timeout\n        bounds how long the caller waits; it does not stop the worker thread\n        created by `asyncio.to_thread`.\n\n        `max_count` is forwarded when the concrete `grep` accepts it (so the\n        search can bound itself); backends that don't accept it run uncapped and\n        are trimmed afterward. Either way the return value is always passed","sourceCodeStart":538,"sourceCodeEnd":574,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/protocol.py#L538-L574","documentation":"The base Backend class defines `grep` as an abstract method raising NotImplementedError; subclasses must implement content search to support the grep tool. Calling `grep` on a backend without an override raises this error. `_grep_backend` (the middleware path backing the grep tool) invokes it, so agents attached to such a backend fail on any grep request.","triggerScenarios":"Agent issues a grep tool call against a custom backend that implements read/write but not grep; direct call backend.grep(pattern) on a partial subclass or on Backend itself.","commonSituations":"Custom object-store or database backends that skip search; stub backends in tests when the agent unexpectedly calls grep; missing override after renaming during a refactor.","solutions":["Implement `grep(self, pattern, path=None, glob=None, ...) -> GrepResult` in your backend subclass (regex or literal search over readable files).","If search is intentionally unsupported, have grep return a GrepResult with an error field instead of raising, and disable the grep tool for the agent.","Use or compose with a backend that implements grep (e.g. filesystem backend) when possible."],"exampleFix":"// before\nclass ApiBackend(Backend):\n    def read(self, file_path, offset=0, limit=2000): ...\n    # no grep -> agent grep tool raises NotImplementedError\n// after\nclass ApiBackend(Backend):\n    def read(self, file_path, offset=0, limit=2000): ...\n    def grep(self, pattern, path=None, glob=None, **kwargs):\n        return search_remote_files(pattern, path=path, glob=glob)","handlingStrategy":"try-catch","validationCode":"if type(backend).grep is Backend.grep:\n    raise RuntimeError('backend does not implement grep; disable the grep tool or switch backends')","typeGuard":"def supports_grep(backend) -> bool:\n    return type(backend).grep is not Backend.grep","tryCatchPattern":"try:\n    result = backend.grep(pattern, path=path)\nexcept NotImplementedError:\n    return GrepResult(matches=[], error='grep not supported by this backend')","preventionTips":["Match exposed agent tools to backend capabilities (don't enable grep on backends without search).","Implement grep via streaming reads + regex if the store has no native search.","Cover grep in backend integration tests so the gap surfaces before an agent hits it."],"tags":["not-implemented","abstract-method","backend-protocol"],"backgroundTag":"not-implemented","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}