langchain-ai/deepagents · error · InvalidGlobPatternError

Path traversal not allowed in glob pattern {pattern!r}

Error message

Path traversal not allowed in glob pattern {pattern!r}

What it means

`compile_grep_include_glob` compiles include/exclude glob patterns used by glob and grep across all backends. Patterns containing a literal `..` path component are rejected up-front with `InvalidGlobPatternError` so traversal cannot behave inconsistently between backends (accepted in one, silently empty in another).

Source

Thrown at libs/deepagents/deepagents/backends/utils.py:146

    Args:
        pattern: Glob include pattern.

    Returns:
        Predicate accepting a search-root-relative POSIX path; returns True when
        the path is included by `pattern`.

    Raises:
        InvalidGlobPatternError: If the pattern contains a `..` segment, or if
            `wcmatch` refuses it (e.g. brace expansion past its limit). Note
            most malformed patterns (`*.{py`, `[a-`) do not raise -- they
            compile and simply match nothing.
    """
    # Reject traversal here rather than per-backend: every backend routes
    # through this function, so a single check keeps `../*.py` from being an
    # exception in one backend and a silent empty result in another.
    if ".." in pattern.replace("\\", "/").split("/"):
        msg = f"Path traversal not allowed in glob pattern {pattern!r}"
        raise InvalidGlobPatternError(msg)

    flags = wcglob.BRACE | wcglob.GLOBSTAR
    # A leading `/` anchors to the search root: strip it so it matches against
    # the (slash-less) relative path, but decide anchoring from the original
    # pattern so `/*.py` stays root-anchored instead of collapsing to a
    # basename-at-any-depth match.
    anchored = "/" in pattern
    try:
        compiled = wcglob.compile(pattern.lstrip("/"), flags=flags)
    except Exception as exc:
        # `wcmatch` only raises private types (`wcmatch._wcparse.PatternLimitException`),
        # so catch broadly and re-raise a public type: every backend can then catch
        # one public type instead of importing from a private module. Log first --
        # the breadth also swallows genuine bugs (a non-`str` pattern, a wcmatch
        # version bump), which would otherwise reach the user as "invalid pattern"
        # for a pattern that is perfectly valid.
        logger.warning("wcmatch refused glob pattern %r (%s): %s", pattern, type(exc).__name__, exc)
        msg = f"Invalid glob pattern {pattern!r}: {exc}"

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Remove the `..` component: anchor the pattern to the search root instead (e.g. `**/*.py`)
  2. Pass the intended root as the search path/`path=` argument rather than climbing with `..` in the pattern
  3. Sanitize or reject user/LLM-supplied globs containing `..` before invoking the tool
  4. Catch `InvalidGlobPatternError` to return a clear tool error instead of crashing

Example fix

// before
backend.glob('../workspace/*.py')
// after
backend.glob('*.py', path='/workspace/')
Defensive patterns

Strategy: validation

Validate before calling

def safe_glob(pattern: str) -> str:
    if '..' in pattern.replace('\\', '/').split('/'):
        raise ValueError(f'path traversal in glob: {pattern!r}')
    return pattern
backend.glob(safe_glob('**/*.py'), path='/workspace')

Type guard

def is_safe_glob(pattern: object) -> bool:
    return isinstance(pattern, str) and '..' not in pattern.replace('\\', '/').split('/')

Try / catch

from deepagents.backends.utils import InvalidGlobPatternError
try:
    files = backend.glob(pattern)
except InvalidGlobPatternError:
    files = backend.glob('**/*')  # safe fallback pattern

Prevention

When it happens

Trigger: Calling `glob('**/../*.py')` or passing an include/exclude glob like `'../src/*.py'` to grep; building glob strings by naive concatenation of a relative parent path with a wildcard.

Common situations: Letting an LLM-generated tool call supply the glob; constructing patterns from user-supplied subdirectories; older code that used filesystem-style relative globs now routed through the virtual path layer.

Related errors


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