shareAI-lab/learn-claude-code · error · ValueError

Path escapes workspace: {p}

Error message

Path escapes workspace: {p}

What it means

The same sandbox guard at agents/s11_autonomous_agents.py:386 in the autonomous long-running agent. Because this agent runs unattended for long stretches, a path rejection here will typically be retried by the loop until context fills — the guard semantics are unchanged from s09/s10 (_safe_path over WORKDIR).

Source

Thrown at agents/s11_autonomous_agents.py:386

        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

  1. Reinforce relative-path discipline in the system prompt for long-running loops
  2. Prune absolute-path strings from context (compact) so the model stops copying them
  3. Verify launch cwd in the runner script before starting the loop

Example fix

# before
_safe_path("/var/data/session_9.json")  # ValueError: Path escapes workspace

# after
_safe_path("data/session_9.json")
Defensive patterns

Strategy: validation

Validate before calling

import os
from pathlib import Path

def autonomous_safe_rel(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 = autonomous_safe_rel(next_path, WORKDIR)
if rel is None:
    log(f"dropping escaping path {next_path}"); next_path = None

Type guard

def is_loop_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:
    log(f"sandbox rejection: {p}")
    return f"Path {p} escapes the workspace. Use paths relative to {WORKDIR}. Do not retry unchanged."

Prevention

When it happens

Trigger: Autonomous turns where the model drifts to absolute paths (often after many compactions or after copying paths from earlier tool output), `../` traversals, or symlinks pointing outside the workspace. A wrong launch cwd makes every nontrivial relative target escape too.

Common situations: Long autonomous sessions where earlier absolute paths keep being re-quoted. Workspaces containing node_modules-style symlink farms. Unattended runs launched from cron/shell with an unexpected cwd.

Related errors


AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14). Data as JSON: /api/errors/beb05c11bf97c582. Report an issue: GitHub.