HKUDS/Vibe-Trading · error · ValueError

Path escapes the workspace root

Error message

Path {p!r} escapes the workspace root

What it means

safe_path expands the input, resolves it against the workspace base, and requires the resolved path to stay inside base via Path.relative_to. Anything that resolves outside (absolute path elsewhere, '..' traversal, symlink escaping) raises this error.

Solutions

  1. Use paths relative to the workspace root without '..' segments
  2. Place needed files inside workdir first
  3. If a file legitimately lives elsewhere, add its directory via the allowed-roots env var instead of bypassing

Example fix

# before
safe_path("../../etc/passwd", workdir)
# after
safe_path("data/input.csv", workdir)
Defensive patterns

Strategy: type-guard

Validate before calling

from pathlib import Path
cand = (workdir / file_path).resolve()
if workdir not in cand.parents and cand != workdir:
    raise ArgumentError(f"{file_path} escapes workspace")

Type guard

def stays_inside(p: str, base: Path) -> bool:
    try:
        (base / p).resolve().relative_to(base)
        return True
    except ValueError:
        return False

Try / catch

try:
    resolved = safe_path(file_path, workdir)
except ValueError as e:
    if "escapes the workspace root" in str(e):
        file_path = relocate_into(file_path, workdir)

Prevention

When it happens

Trigger: Passing '../..' style relative paths, absolute paths outside workdir, or a symlink inside workdir pointing outside that resolves beyond the root.

Common situations: Generated code using absolute temp paths, prompts referencing files outside the workspace, or symlinks created by build tooling.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/41c80d037553244c. Report an issue: GitHub.

Appendix: source

Thrown at agent/src/tools/path_utils.py:73

        Absolute resolved path inside `workdir`.

    Raises:
        ValueError: If `p` uses a UNC share, or its resolved form escapes
            `workdir`. Callers surface this back to the LLM as a tool error.
    """
    _rejects_unc(p)
    base = Path(workdir).resolve()
    # Expand ~ so home-relative paths (e.g. ~/.vibe-trading/scripts/foo.py)
    # resolve correctly instead of being treated as literal directory names.
    expanded = Path(p).expanduser()
    if expanded.is_absolute():
        resolved = expanded.resolve()
    else:
        resolved = (base / p).resolve()
    try:
        resolved.relative_to(base)
    except ValueError as exc:
        raise ValueError(f"Path {p!r} escapes the workspace root") from exc
    return resolved


def _agent_root() -> Path:
    """Return the agent package root."""
    return Path(__file__).resolve().parents[2]


def _configured_file_roots() -> list[Path]:
    """Return file roots configured through the environment."""
    raw = get_env_config().api.vibe_trading_allowed_file_roots
    roots: list[Path] = []
    for item in raw.split(","):
        item = item.strip()
        if not item:
            continue
        _rejects_unc(item)
        roots.append(Path(item).expanduser().resolve())

View on GitHub (pinned to 80ffdda44c)