shareAI-lab/learn-claude-code · error · GoalError
path escapes the current repository
Error message
path escapes the current repository
What it means
AgentSession._safe_path resolved a tool-supplied relative path (workdir / path, then .resolve()) and found it does not lie inside self.workdir (s17_goal_loop/code.py:753). The resolution step follows symlinks and '../' segments, so this fires on sandbox escapes like '../../etc/passwd', absolute-path tricks after joining, or a symlink inside the repo pointing outside.
Source
Thrown at s17_goal_loop/code.py:753
f"Evaluator: {decision.reason}\n"
"Continue working and surface the missing evidence."
),
}
)
continue
self.trigger_hooks("Stop", self.messages)
return SessionResult(
text=text,
status=decision.action,
reason=decision.reason,
)
def _safe_path(self, path: str) -> Path:
candidate = (self.workdir / path).resolve()
try:
candidate.relative_to(self.workdir)
except ValueError as error:
raise GoalError("path escapes the current repository") from error
return candidate
def _run_tool(self, name: str, arguments: dict[str, Any]) -> str:
if name == "bash":
command = str(arguments["command"])
result = subprocess.run(
command,
shell=True,
cwd=self.workdir,
capture_output=True,
text=True,
timeout=120,
check=False,
)
output = (result.stdout + result.stderr).strip()
output = output[-29950:]
return f"exit_code={result.returncode}\n{output}"
View on GitHub (pinned to 985456f4ad)
Solutions
- If the access is legitimate, copy the needed file into the repo or run the session with a workdir that contains it
- Rephrase the task so the model only references in-repo paths; add the constraint to the system/task prompt
- Remove or relocate symlinks inside the repo that point outside the root
- Catch GoalError around session runs and treat it as a tool-misuse signal: log and let the agent retry with a corrected path
Example fix
# before # model tool call: read_file ../../~/.gitconfig # after # copy the file into the repo first, then let the model read it cp ~/.gitconfig ./.gitconfig.reference # model tool call: read_file .gitconfig.reference
Defensive patterns
Strategy: try-catch
Validate before calling
def resolves_inside(workdir: Path, relative: str) -> bool:
try:
(workdir / relative).resolve().relative_to(workdir.resolve())
return True
except ValueError:
return False
if not resolves_inside(session.workdir, tool_args.get("path", "")):
# reject or rewrite the path before dispatching the tool Type guard
def is_safe_relative_path(workdir: Path, path: object) -> bool:
if not isinstance(path, str) or not path:
return False
try:
(workdir / path).resolve().relative_to(workdir.resolve())
return True
except ValueError:
return False Try / catch
try:
await session.submit(query)
except GoalError as error:
if "escapes the current repository" in str(error):
log.warning("tool attempted out-of-repo path; retrying with constrained prompt")
continue # let the agent see the error and choose an in-repo path
raise Prevention
- Tell the model in the system prompt that only in-repo paths are readable/writable
- Audit the repo for symlinks pointing outside the root before running sessions
- Treat this error as a tool-misuse signal to feed back to the agent, not a crash
When it happens
Trigger: A tool call (read/write/edit) from the model passes a path containing '..' that escapes the repo root, or a path that resolves through a symlink to a location outside workdir. For example read_file with '../../~/.ssh/config' while workdir is the repo.
Common situations: The model tries to read config or logs outside the project (e.g. ~/.gitconfig, /tmp artifacts); the repo contains a symlink (node_modules-style links, linked assets) to an external directory; generated code passes absolute paths which get joined and resolve outside root.
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/9c53536fae066f26.
Report an issue: GitHub.