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
- Prefix the pattern with '/' (e.g. '/src/foo')
- Normalize/resolve the path to absolute form before constructing the permission
- 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
- Normalize all permission patterns to absolute POSIX form at config load
- Reject relative paths in user-facing config with a clear message
- Use posixpath joins that preserve the leading '/'
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
- read_file must be included in tools; it is required by Files
- max_execute_timeout must be positive, got {max_execute_timeo
- allow_list must not be empty; disable shell access instead
- interpreter_ptc='all' exposes every host tool to PTC calls t
- Invalid interpreter_ptc string {ptc!r}; expected 'safe', 'al
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/47ebf52ded994f5e.
Report an issue: GitHub.