shareAI-lab/learn-claude-code · error · ValueError
Path escapes workspace: {p}
Error message
Path escapes workspace: {p} What it means
The workspace sandbox guard at agents/s09_agent_teams.py:259 (_safe_path, underscore-prefixed because this script layers team tools on the s02 base). Same semantics: join onto WORKDIR, resolve(), require the result under WORKDIR. It governs the shared base file tools used by team members.
Source
Thrown at agents/s09_agent_teams.py:259
if not self.config["members"]:
return "No teammates."
lines = [f"Team: {self.config['team_name']}"]
for m in self.config["members"]:
lines.append(f" {m['name']} ({m['role']}): {m['status']}")
return "\n".join(lines)
def member_names(self) -> list:
return [m["name"] for m in self.config["members"]]
TEAM = TeammateManager(TEAM_DIR)
# -- Base tool implementations (these base tools are unchanged from s02) --
def _safe_path(p: str) -> Path:
path = (WORKDIR / p).resolve()
if not path.is_relative_to(WORKDIR):
raise ValueError(f"Path escapes workspace: {p}")
return path
def _run_bash(command: str) -> str:
dangerous = ["rm -rf /", "sudo", "shutdown", "reboot", "> /dev/"]
if any(d in command for d in dangerous):
return "Error: Dangerous command blocked"
try:
r = subprocess.run(
command, shell=True, cwd=WORKDIR,
capture_output=True, text=True, timeout=120,
)
out = (r.stdout + r.stderr).strip()
return out[:50000] if out else "(no output)"
except subprocess.TimeoutExpired:
return "Error: Timeout (120s)"
View on GitHub (pinned to 985456f4ad)
Solutions
- Normalize paths to workspace-relative before file tool calls, especially paths received from other teammates
- Keep team config and message conventions on relative paths
- Launch the harness from the workspace root
Example fix
# before (teammate message: "check /tmp/errlookup-AdzUmp/src/api.py")
_safe_path("/tmp/errlookup-AdzUmp/src/api.py")
# ValueError: Path escapes workspace
# after
import os
_safe_path(os.path.relpath("/tmp/errlookup-AdzUmp/src/api.py", WORKDIR)) # "src/api.py" Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
def normalize_received_path(p: str, workdir: Path) -> str | None:
"""Teammates send paths in any form; make them workspace-relative or drop them."""
try:
cand = Path(p)
abs_c = cand if cand.is_absolute() else (workdir / cand)
abs_c = abs_c.resolve()
return os.path.relpath(abs_c, workdir) if abs_c.is_relative_to(workdir) else None
except (OSError, ValueError, RuntimeError):
return None
rel = normalize_received_path(teammate_path, WORKDIR)
assert rel, f"teammate path {teammate_path} escapes workspace" Type guard
def is_team_safe_path(p: object, workdir) -> bool:
if not isinstance(p, str) or not p:
return False
try:
return (workdir / p).resolve().is_relative_to(workdir)
except (OSError, RuntimeError):
return False Try / catch
try:
path = _safe_path(p)
except ValueError:
return f"Teammate path {p} rejected by sandbox. Re-issue as a workspace-relative path." Prevention
- Normalize any path received from a teammate before using it in a tool call
- Keep team config files on relative paths
- Re-state file locations relatively when relaying work between members
When it happens
Trigger: A teammate agent passes an absolute path or `../` traversal to a file tool — often a path quoted verbatim from a teammate message or from the team config (TEAM_DIR files may embed absolute paths). Symlink escapes and cwd mismatch also trigger it.
Common situations: Team protocols where one member posts an absolute path and another copies it into a tool call. Harness started outside the workspace. Teammate config files referencing machine-specific paths.
Related errors
- Path escapes workspace: {p}
- Path escapes workspace: {p}
- Path escapes workspace: {p}
- Path escapes workspace: {p}
- Path escapes workspace: {p}
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/9347abe68665c2c8.
Report an issue: GitHub.