langchain-ai/deepagents · error · ValueError
Path traversal not allowed: {path}
Error message
Path traversal not allowed: {path} What it means
`validate_path` normalizes virtual filesystem paths and rejects anything that escapes the virtual root. A `..` path component or a leading `~` raises ValueError 'Path traversal not allowed'. The check is per path component (not substring), so legitimate names like `foo..bar.txt` still pass.
Source
Thrown at libs/deepagents/deepagents/backends/utils.py:702
Windows absolute path (e.g., `C:/...`), or does not start with an
allowed prefix when `allowed_prefixes` is specified.
Example:
```python
validate_path("foo/bar") # Returns: "/foo/bar"
validate_path("/./foo//bar") # Returns: "/foo/bar"
validate_path("../etc/passwd") # Raises ValueError
validate_path(r"C:\\Users\\file.txt") # Raises ValueError
validate_path("/data/file.txt", allowed_prefixes=["/data/"]) # OK
validate_path("/etc/file.txt", allowed_prefixes=["/data/"]) # Raises ValueError
```
"""
# Check for traversal as a path component (not substring) to avoid
# false-positive rejection of legitimate filenames like "foo..bar.txt"
parts = PurePosixPath(to_posix_path(path)).parts
if ".." in parts or path.startswith("~"):
msg = f"Path traversal not allowed: {path}"
raise ValueError(msg)
# Reject Windows absolute paths (e.g., C:\..., D:/...)
if re.match(r"^[a-zA-Z]:", path):
msg = f"Windows absolute paths are not supported: {path}. Please use virtual paths starting with / (e.g., /workspace/file.txt)"
raise ValueError(msg)
normalized = os.path.normpath(path)
normalized = normalized.replace("\\", "/")
if not normalized.startswith("/"):
normalized = f"/{normalized}"
# Defense-in-depth: verify normpath didn't produce traversal
if ".." in normalized.split("/"):
msg = f"Path traversal detected after normalization: {path} -> {normalized}"
raise ValueError(msg)
if allowed_prefixes is not None and not any(normalized.startswith(prefix) for prefix in allowed_prefixes):View on GitHub (pinned to a1af029e6e)
Solutions
- Use absolute virtual paths rooted at `/` (e.g. `/workspace/file.txt`) without `..` or `~` components
- Resolve/normalize paths against an explicit base directory yourself and verify containment before calling the backend
- Sanitize user/LLM input: strip `~`, collapse or reject `..` components
- Catch the ValueError and return a friendly tool-error telling the agent to use virtual paths
Example fix
// before
backend.read('~/secrets.txt')
backend.read('/workspace/../etc/passwd')
// after
backend.read('/workspace/notes.txt') Defensive patterns
Strategy: validation
Validate before calling
from pathlib import PurePosixPath
def is_safe_virtual_path(path: str) -> bool:
if path.startswith('~'):
return False
parts = PurePosixPath(path.replace('\\', '/')).parts
if '..' in parts:
return False
return True
if is_safe_virtual_path(p):
backend.read(p) Type guard
def is_safe_path(path: object) -> bool:
if not isinstance(path, str) or path.startswith('~'):
return False
from pathlib import PurePosixPath
return '..' not in PurePosixPath(path.replace('\\', '/')).parts Try / catch
try:
content = backend.read(path)
except ValueError as exc:
if 'Path traversal not allowed' in str(exc):
raise ToolError(f'use absolute /-rooted virtual paths, got {path!r}') from exc
raise Prevention
- Validate/normalize agent- and user-supplied paths before backend calls
- Reject `~` and `..` components in tool-input schemas
- Always use absolute virtual paths rooted at `/`
- Document the virtual path convention in agent prompts so models emit valid paths
When it happens
Trigger: Calling backend `read`/`write`/`ls`/`edit`/`glob` with paths like `/../etc/passwd`, `a/../../b`, or `~/notes.txt`; LLM-generated tool arguments containing `..` or `~`; user input interpolated unvalidated into paths.
Common situations: Agents hallucinating home-relative (`~`) paths; users pasting shell-style paths; composing paths from user-controlled directory names without sanitization.
Related errors
- Path traversal detected after normalization: {path} -> {norm
- Invalid agent name: {agent_name!r}. Agent names can only con
- allow_fs_tools must be None or a non-empty list
- interpreter_ptc='all' exposes every host tool to PTC calls t
- temporary artifact is not a regular file
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/7d6a116fbdcda201.
Report an issue: GitHub.