langchain-ai/deepagents · error · ValueError

Permission path must start with '/': {path!r}

Error message

Permission path must start with '/': {path!r}

What it means

FilesystemPermission validates its path patterns in __post_init__; every pattern must be an absolute POSIX-style path starting with '/'. Relative patterns are rejected with this ValueError to keep permission matching unambiguous.

Source

Thrown at libs/deepagents/deepagents/middleware/filesystem.py:413

    - `"allow"` (default): the call proceeds.
    - `"deny"`: the tool returns a permission-denied error.
    - `"interrupt"`: the call is paused for human approval via
        [`HumanInTheLoopMiddleware`][langchain.agents.middleware.HumanInTheLoopMiddleware].

        Best paired with patterns that have a literal leading anchor (e.g.,
        `/secrets/**`, `/projects/*/secrets/**`). Bulk tools
        (`ls`/`glob`/`grep`) fire the interrupt based on whether their
        search subtree could overlap the rule's anchored prefix, so a fully
        unanchored pattern (`/**/secrets`) collapses to `/` and
        conservatively over-fires for any bulk call.
    """

    def __post_init__(self) -> None:
        """Validate permission path patterns."""
        for path in self.paths:
            if not path.startswith("/"):
                msg = f"Permission path must start with '/': {path!r}"
                raise ValueError(msg)
            parts = PurePosixPath(path.replace("\\", "/")).parts
            if ".." in parts:
                msg = f"Permission path must not contain '..': {path!r}"
                raise ValueError(msg)
            if "~" in parts:
                msg = f"Permission path must not contain '~': {path!r}"
                raise NotImplementedError(msg)


def _check_fs_permission(
    rules: list[FilesystemPermission],
    operation: FilesystemOperation,
    path: str,
) -> Literal["allow", "deny", "interrupt"]:
    for rule in rules:
        if operation not in rule.operations:
            continue
        if any(wcglob.globmatch(path, pattern, flags=_FS_WCMATCH_FLAGS) for pattern in rule.paths):

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Prefix the pattern with '/' (e.g. '/src/foo')
  2. Normalize/resolve the path to absolute form before constructing the permission
  3. Reject or transform relative patterns at your config-load boundary

Example fix

// before
FilesystemPermission(paths=["src/secrets"])
// after
FilesystemPermission(paths=["/src/secrets"])
Defensive patterns

Strategy: validation

Validate before calling

def ensure_absolute(p: str) -> str:
    if not p.startswith("/"):
        raise ValueError(f"permission path must be absolute: {p!r}")
    return p

Try / catch

try:
    perm = FilesystemPermission(paths=paths)
except ValueError as e:
    logger.error("bad permission pattern: %s", e)
    raise

Prevention

When it happens

Trigger: Creating FilesystemPermission(paths=[...]) with an entry like 'src/foo' or 'foo.txt' (no leading slash).

Common situations: Building permission rules from user-relative CLI input; reading patterns from config that were written relative to a project dir; joining paths without a leading '/'.

Related errors


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