langchain-ai/deepagents · error · NotImplementedError

NotImplementedError raised by abstract `glob` (backend does

Error message

NotImplementedError raised by abstract `glob` (backend does not implement `glob`)

What it means

The base Backend class defines `glob` as an abstract method raising NotImplementedError; subclasses must implement pattern-based file matching. The docstring warns backends must return ABSOLUTE paths — deny rules are only evaluated against absolute patterns, so a relative path would silently bypass them. Hitting NotImplementedError means the backend in use never implemented glob.

Source

Thrown at libs/deepagents/deepagents/backends/protocol.py:653

            path: Optional base directory to search from.

                If omitted, the backend chooses its default search root.

                The pattern is applied relative to this path.

        Returns:
            `GlobResult` with matching files or error. Patterns the matcher
            refuses -- brace expansion past its limit, or a `..` segment -- are
            reported as `error` with `matches=None`, not raised.

            `FileInfo.path` is always absolute. `_check_fs_permission` matches
            `deny` rules against absolute patterns only, so a backend returning
            a relative path silently bypasses every deny rule.

        Raises:
            NotImplementedError: If the backend does not implement `glob`.
        """
        raise NotImplementedError

    async def aglob(self, pattern: str, path: str | None = None) -> "GlobResult":
        """Async version of `glob`."""
        return await asyncio.to_thread(self.glob, pattern, path)

    def write(
        self,
        file_path: str,
        content: str,
    ) -> WriteResult:
        """Write content to a file, creating it or overwriting it if it already exists.

        Args:
            file_path: Absolute path where the file should be written.

                Must start with '/'.
            content: String content to write to the file.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Implement `glob(self, pattern, path=None) -> GlobResult` in your backend, returning absolute paths so permission/deny rules apply.
  2. If globbing is unsupported by the storage system, enumerate candidates yourself and match with fnmatch, returning a valid GlobResult.
  3. Alternatively use a backend with glob support, or disable the glob tool for agents using this backend.

Example fix

// before
class DbBackend(Backend):
    def read(self, file_path, offset=0, limit=2000): ...
// after
import fnmatch
class DbBackend(Backend):
    def read(self, file_path, offset=0, limit=2000): ...
    def glob(self, pattern, path=None):
        matches = [f'/{k}' for k in self.store if fnmatch.fnmatch(f'/{k}', pattern)]
        return GlobResult(files=matches)
Defensive patterns

Strategy: try-catch

Validate before calling

if type(backend).glob is Backend.glob:
    raise RuntimeError('backend does not implement glob; disable the glob tool or switch backends')

Type guard

def supports_glob(backend) -> bool:
    return type(backend).glob is not Backend.glob

Try / catch

try:
    result = backend.glob(pattern)
except NotImplementedError:
    return GlobResult(files=[], error='glob not supported by this backend')

Prevention

When it happens

Trigger: Agent issues a glob tool call (or middleware calls backend.glob(pattern, path)) on a partial backend subclass; instantiating Backend directly and calling glob.

Common situations: Minimal custom backends that only cover read/write; virtual or remote backends without pattern-matching support; tests using stubs when the model calls the glob tool.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/23108c6fc7b74dd3. Report an issue: GitHub.