langchain-ai/deepagents · error · NotImplementedError
Permission path must not contain '~': {path!r}
Error message
Permission path must not contain '~': {path!r} What it means
FilesystemPermission patterns must not contain a '~' component; home-directory shorthand is not supported by the permission matcher, so it raises NotImplementedError rather than silently mis-matching. Use explicit absolute paths instead.
Source
Thrown at libs/deepagents/deepagents/middleware/filesystem.py:420
(`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):
return rule.mode
return "allow"
def _wildcard_delete_overlap(pattern: str, anchor: str, target: str) -> bool:
"""Check whether a wildcard deny pattern overlaps a recursive delete target.
View on GitHub (pinned to a1af029e6e)
Solutions
- Call os.path.expanduser on the pattern before constructing the permission, then verify it still starts with '/'
- Replace '~' with the concrete absolute home path
- Drop '~' from config templates and document absolute paths only
Example fix
// before
FilesystemPermission(paths=["~/.ssh/**"])
// after
FilesystemPermission(paths=[os.path.expanduser("~/.ssh/**")]) Defensive patterns
Strategy: validation
Validate before calling
import os
def expand_tilde(p: str) -> str:
expanded = os.path.expanduser(p)
if "~" in expanded.split("/"):
raise ValueError(f"unexpandable '~' in permission path: {p!r}")
return expanded Try / catch
try:
perm = FilesystemPermission(paths=[os.path.expanduser(p) for p in paths])
except (ValueError, NotImplementedError) as e:
logger.error("bad permission path: %s", e)
raise Prevention
- Always os.path.expanduser home-relative patterns before use
- Document that permission patterns are absolute paths only
- Validate patterns early in config loading
When it happens
Trigger: Constructing FilesystemPermission with '~' or '~/foo' (or a segment exactly '~') in the path pattern.
Common situations: Copying shell-style rules like '~/.ssh/**' into permission config; expanding user home paths lazily instead of via os.path.expanduser at config time.
Related errors
- Permission path must start with '/': {path!r}
- read_file must be included in tools; it is required by Files
- max_execute_timeout must be positive, got {max_execute_timeo
- Cannot determine whether {str(left)!r} is {str(right)!r}: {e
- Invalid DEEPAGENTS_HOME {str(root)!r}: exists but cannot be
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/aa6592c94f1f440f.
Report an issue: GitHub.