NousResearch/hermes-agent · error · PermissionError
Path '{resolved}' is outside the session cwd '{root}'.
Error message
Path '{resolved}' is outside the session cwd '{root}'. What it means
An ACP file-system request resolved to a path outside the session's cwd. After requiring an absolute path, _ensure_path_within_cwd resolves symlinks and requires the result to be relative_to(Path(cwd).resolve()); a ValueError from relative_to becomes this PermissionError. It confines the Copilot ACP process to the session workspace.
Source
Thrown at agent/copilot_acp_client.py:379
cursor = max(cursor, end)
if cursor < len(text):
parts.append(text[cursor:])
cleaned = "\n".join(p.strip() for p in parts if p and p.strip()).strip()
return extracted, cleaned
def _ensure_path_within_cwd(path_text: str, cwd: str) -> Path:
candidate = Path(path_text)
if not candidate.is_absolute():
raise PermissionError("ACP file-system paths must be absolute.")
resolved = candidate.resolve()
root = Path(cwd).resolve()
try:
resolved.relative_to(root)
except ValueError as exc:
raise PermissionError(f"Path '{resolved}' is outside the session cwd '{root}'.") from exc
return resolved
class _ACPChatCompletions:
def __init__(self, client: "CopilotACPClient"):
self._client = client
def create(self, **kwargs: Any) -> Any:
return self._client._create_chat_completion(**kwargs)
class _ACPChatNamespace:
def __init__(self, client: "CopilotACPClient"):
self.completions = _ACPChatCompletions(client)
class CopilotACPClient:
"""Minimal OpenAI-client-compatible facade for Copilot ACP."""View on GitHub (pinned to c896c09c42)
Solutions
- Run the session from a directory that contains everything the agent needs, so cwd covers the accessed paths.
- Check for symlinks in the failing path (ls -l) and replace/relocate ones that escape the workspace.
- If a legitimate need exists to work on multiple roots, start Hermes in a parent directory containing them.
Example fix
# before — session started in subdir, Copilot reaches for sibling hermes # cwd=/repo/packages/app → path /repo/packages/lib/x.ts denied # after — start at the repo root so cwd contains both hermes # cwd=/repo
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def within_cwd(path_text: str, cwd: str) -> bool:
resolved = Path(path_text).resolve()
try:
resolved.relative_to(Path(cwd).resolve())
return True
except ValueError:
return False Try / catch
try:
handle_fs_request(params)
except PermissionError as e:
if "outside the session cwd" in str(e):
# relocate the work under cwd or restart session in a wider root
... Prevention
- Start Hermes in a parent directory that contains all working files
- Avoid symlinks that escape the session cwd
- Keep Copilot-scoped work inside one workspace root
When it happens
Trigger: An fs/read_text_file or fs/write_text_file from the Copilot ACP process targeting an absolute path outside the session cwd, or a path inside the cwd that is a symlink resolving outside it (candidate.resolve() follows links).
Common situations: Copilot CLI trying to read config or caches from $HOME while the session cwd is a project directory; symlinked dependencies (monorepo layouts) escaping the workspace; probing behavior from a misbehaving ACP peer.
Related errors
- Write denied: '{path}' requires interactive approval and can
- path is outside the allowed workspace
- ACP file-system paths must be absolute.
- Could not start Copilot ACP command '{self._acp_command}'. I
- Copilot ACP process did not expose stdin/stdout pipes.
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/28fef2fcc0edfe48.
Report an issue: GitHub.