FoundationAgents/OpenManus · warning · ValueError
Path contains potentially unsafe patterns
Error message
Path contains potentially unsafe patterns
What it means
Raised as ValueError by DockerSandbox._safe_resolve_path (app/sandbox/core/sandbox.py:246) when any single path segment equals '..' — a deliberate path-traversal block before the path is used with Docker APIs. It fires on the raw string segments, so even a benign-looking 'foo/../bar' is rejected; there is no allowlist.
Source
Thrown at app/sandbox/core/sandbox.py:246
except Exception as e:
raise RuntimeError(f"Failed to write file: {e}")
def _safe_resolve_path(self, path: str) -> str:
"""Safely resolves container path, preventing path traversal.
Args:
path: Original path.
Returns:
Resolved absolute path.
Raises:
ValueError: If path contains potentially unsafe patterns.
"""
# Check for path traversal attempts
if ".." in path.split("/"):
raise ValueError("Path contains potentially unsafe patterns")
resolved = (
os.path.join(self.config.work_dir, path)
if not os.path.isabs(path)
else path
)
return resolved
async def copy_from(self, src_path: str, dst_path: str) -> None:
"""Copies a file from the container.
Args:
src_path: Source file path (container).
dst_path: Destination path (host).
Raises:
FileNotFoundError: If source file does not exist.
RuntimeError: If copy operation fails.View on GitHub (pinned to 52a13f2a57)
Solutions
- Sanitize on the caller side: use os.path.basename for filenames, or normalize and re-verify the result stays under work_dir.
- Strip/reject '..' segments (and ideally '..\\' too) before passing user-derived strings.
- Use absolute paths already known to be under the work_dir volume.
- For user uploads, generate server-side safe names (uuid + sanitized basename).
Example fix
# before
await sandbox.write_file(f"uploads/{user_filename}", data) # user_filename may contain '..'
# after
safe = os.path.basename(user_filename.replace("..", "_")).strip() or "upload.bin"
await sandbox.write_file(f"uploads/{safe}", data) Defensive patterns
Strategy: validation
Validate before calling
def safe_container_path(path: str, work_dir: str) -> str:
parts = [p for p in path.replace("\\", "/").split("/") if p not in ("", ".", "..")]
candidate = os.path.normpath(os.path.join(work_dir, *parts))
if not candidate.startswith(os.path.normpath(work_dir)):
raise ValueError(f"escapes work_dir: {path!r}")
return candidate Type guard
def is_safe_path(path: str) -> bool:
return ".." not in path.replace("\\", "/").split("/") Try / catch
try:
await sandbox.write_file(user_path, data)
except ValueError as e:
if "unsafe patterns" in str(e):
user_path = os.path.basename(user_path) # degrade to basename and retry once Prevention
- Never pass unvalidated user/LLM strings as container paths
- Prefer basenames under a fixed uploads dir
- Normalize with normpath then re-verify containment under work_dir
- Reject backslash traversal too — the built-in check only splits on '/'
When it happens
Trigger: Passing a path containing '..' to read_file/write_file/copy_from/copy_to; LLM-generated tool arguments that include traversal; joining an unvalidated user string into a container path; normalizing paths with os.path.normpath on the caller side and still containing '..' segments that escape the root.
Common situations: Agent tool receives ' ../../etc/passwd' style inputs; caller pre-normalizes 'a/./b/../c' — normpath keeps '..' segments when they would climb above the base; Windows-style '..\\' does NOT match the split('/') check and may bypass it (defense depth note).
Related errors
- Server URL is required for SSE connection
- Command is required for stdio connection
- Unsupported connection type: {self.connection_type}
- password must be provided
- Tool calls required but none provided
AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15).
Data as JSON: /api/errors/011a71cbd6acf89b.
Report an issue: GitHub.