shareAI-lab/learn-claude-code · error · ValueError
Path escapes workspace: {p}
Error message
Path escapes workspace: {p} What it means
Identical guard at agents/s10_team_protocols.py:300 — this stage adds structured team protocols on top of s09 and reuses _safe_path for the base file tools. Any file tool path that resolves outside WORKDIR (Path.cwd() at launch) is rejected.
Source
Thrown at agents/s10_team_protocols.py:300
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
- Make handoff/protocol messages use workspace-relative paths
- Convert absolute paths to relative before file tool calls
- Start the agent with cwd = workspace root
Example fix
# before
_safe_path("/home/beagle/proj/notes.md") # ValueError: Path escapes workspace
# after
_safe_path("notes.md") Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
def relay_safe_path(p: str, workdir: Path) -> str | None:
try:
cand = Path(p)
abs_c = (cand if cand.is_absolute() else workdir / cand).resolve()
return os.path.relpath(abs_c, workdir) if abs_c.is_relative_to(workdir) else None
except (OSError, ValueError, RuntimeError):
return None
rel = relay_safe_path(handoff_path, WORKDIR)
assert rel, "handoff path escapes workspace; request a relative path in the protocol" Type guard
def is_protocol_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"Protocol path {p} rejected. Handoffs must reference workspace-relative paths." Prevention
- Encode relative paths in the protocol/handoff message format itself
- Convert any absolute path to relpath at the receiving end before tool use
- Validate handoff payloads against the sandbox before broadcasting them
When it happens
Trigger: File tool calls carrying absolute paths or traversals, typically paths copied from protocol messages, handoff notes, or teammate configs. Symlink escape and wrong launch cwd are the other two routes.
Common situations: Protocol handoffs that reference files by absolute path; models forwarding those verbatim. Harness launched from a parent directory so WORKDIR is too narrow.
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/b225df8fadcafa10.
Report an issue: GitHub.