shareAI-lab/learn-claude-code · error · ValueError
Path escapes workspace: {p}
Error message
Path escapes workspace: {p} What it means
The workspace sandbox guard repeated at agents/s04_subagent.py:50, shared by parent and subagent in the delegation demo. Both roles' file tools route through safe_path(): join onto WORKDIR, resolve(), require the result to stay under WORKDIR. Subagents inherit the same WORKDIR, so a child asked to read a path outside the workspace gets the same rejection.
Source
Thrown at agents/s04_subagent.py:50
load_dotenv(override=True)
if os.getenv("ANTHROPIC_BASE_URL"):
os.environ.pop("ANTHROPIC_AUTH_TOKEN", None)
WORKDIR = Path.cwd()
client = Anthropic(base_url=os.getenv("ANTHROPIC_BASE_URL"))
MODEL = os.environ["MODEL_ID"]
SYSTEM = f"You are a coding agent at {WORKDIR}. Use the task tool to delegate exploration or subtasks."
SUBAGENT_SYSTEM = f"You are a coding subagent at {WORKDIR}. Complete the given task, then summarize your findings."
# -- Tool implementations shared by parent and child --
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)"
except (FileNotFoundError, OSError) as e:
return f"Error: {e}"
def run_read(path: str, limit: int = None) -> str:
try:View on GitHub (pinned to 985456f4ad)
Solutions
- Scope every delegated task (and file tool call) to workspace-relative paths
- If outside-workspace data is needed, use the bash tool's constrained read (e.g. `cat` with a specific file) rather than the sandboxed file tools, or copy the file into the workspace first
- Rewrite absolute in-workspace paths to relative before the tool call
Example fix
# before (parent -> subagent task) "Read /tmp/errlookup-AdzUmp/docs/plan.md and summarize" # subagent file tool: ValueError: Path escapes workspace # after "Read docs/plan.md and summarize"
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def is_delegation_safe_path(p: str, workdir: Path) -> 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
# parent-side: rewrite the task brief before spawning the subagent
brief = brief.replace(str(workdir) + "/", "") if is_delegation_safe_path(brief_path, workdir) else brief Type guard
def is_relative_child_path(p: object) -> bool:
"""Subagents should only ever receive/emit relative paths."""
return isinstance(p, str) and p != "" and not p.startswith(("/", "~")) and ".." not in Path(p).parts Try / catch
try:
path = safe_path(p)
except ValueError:
return f"Sandbox rejection for {p}. Subagents must use paths relative to {WORKDIR}; ask the parent for a relative path." Prevention
- Write delegation briefs with workspace-relative paths only
- Have subagents convert any absolute path to relpath before file tool use
- Keep outside-workspace data out of subagent scope by design
When it happens
Trigger: The parent delegates "read /var/log/system.log and summarize" and the subagent passes that absolute path to a file tool. Or a subagent follows a `../` reference from a file inside the workspace. Or the model uses an absolute path printed by a bash command's output.
Common situations: Delegation prompts that name files outside the workspace (logs, /etc configs, home-dir files). Subagents quoting absolute paths verbatim from parent instructions. Harness launched from the wrong cwd.
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/7aac7556190f4f7a.
Report an issue: GitHub.