HKUDS/Vibe-Trading · error · ValueError
run_dir is required to write/edit {file_path!r}, or the path
Error message
run_dir is required to write/edit {file_path!r}, or the path must resolve inside allowed {purpose} roots. What it means
When no run_dir is supplied, resolve_safe_path requires the file_path to resolve inside one of the allowed roots for that purpose; otherwise this error explains that run_dir is required for write/edit operations outside allowlisted roots.
Source
Thrown at agent/src/tools/path_utils.py:238
try:
return safe_path(file_path, run_root)
except ValueError as exc:
# Fallback to allowed roots if safe_path containment fails
candidate = Path(file_path).expanduser().resolve()
for root in allowed_roots:
if candidate.is_relative_to(root):
return candidate
raise ValueError(
f"Path {file_path!r} escapes run_dir {run_dir!r} and is not in allowed {purpose} roots."
) from exc
# If no run_dir, path must resolve inside one of the allowed roots
candidate = Path(file_path).expanduser().resolve()
for root in allowed_roots:
if candidate.is_relative_to(root):
return candidate
raise ValueError(
f"run_dir is required to write/edit {file_path!r}, or the path must resolve inside allowed {purpose} roots."
)
def _allowed_run_roots() -> list[Path]:
"""Return all roots allowed for run_dir-based tools."""
raw = get_env_config().api.vibe_trading_allowed_run_roots
configured: list[Path] = []
for item in raw.split(","):
item = item.strip()
if not item:
continue
_rejects_unc(item)
configured.append(Path(item).expanduser().resolve())
roots: list[Path] = []
for root in [*_default_run_roots(), *configured]:
resolved = root.resolve()View on GitHub (pinned to 80ffdda44c)
Solutions
- Create/obtain a run_dir and pass it to the tool
- Or restrict writes to a directory listed in allowed write roots
- Verify the path with expanduser().resolve() matches an allowed root exactly (no symlinks)
Example fix
# before tool.execute(file_path="/home/user/note.md", mode="edit") # after run = create_run_dir() # under allowed run roots tool.execute(file_path=str(run / "note.md"), run_dir=str(run), mode="edit")
Defensive patterns
Strategy: validation
Validate before calling
if run_dir is None:
cand = Path(file_path).expanduser().resolve()
assert any(cand.is_relative_to(r) for r in allowed_write_roots()), "need run_dir or allowed root" Type guard
def can_write_without_run_dir(p: str, roots: list[Path]) -> bool:
c = Path(p).expanduser().resolve()
return any(c.is_relative_to(r) for r in roots) Try / catch
try:
target = resolve_safe_path(file_path, None, purpose="write")
except ValueError as e:
if "run_dir is required" in str(e):
run_dir = create_run_dir(); target = resolve_safe_path(str(run_dir / Path(file_path).name), str(run_dir), purpose="write") Prevention
- Always thread run_dir through write/edit flows
- Create run dirs via the tooling, not ad hoc
- Keep allowed write roots minimal and explicit
When it happens
Trigger: Calling a write/edit tool without run_dir and with a path outside all allowed roots.
Common situations: Ad-hoc scripts invoking file tools directly without creating a run directory, or expecting cwd to be implicitly allowed.
Related errors
- Path {file_path!r} escapes run_dir {run_dir!r} and is not in
- run_dir {p!r} is outside allowed run roots. {_describe_roots
- path must start with "/"
- token_issue_path must start with "/"
- UNC paths are not allowed: {p!r}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/a2432c272d5754e9.
Report an issue: GitHub.