NousResearch/hermes-agent · error · PermissionError
Write denied: '{path}' requires interactive approval and can
Error message
Write denied: '{path}' requires interactive approval and cannot be written through the ACP file bridge. What it means
An fs/write_text_file request from the Copilot ACP process targeted a path that passes the hard deny-list but is approval-gated (e.g. ~/.ssh/config). The ACP shim has no interactive human channel to confirm such writes, so it fails closed with this PermissionError instead of writing silently — interactive tools would prompt, but the bridge cannot.
Source
Thrown at agent/copilot_acp_client.py:742
"jsonrpc": "2.0",
"id": message_id,
"result": {
"content": content,
},
}
except Exception as exc:
response = _jsonrpc_error(message_id, -32602, str(exc))
elif method == "fs/write_text_file":
try:
path = _ensure_path_within_cwd(str(params.get("path") or ""), cwd)
denied = get_write_denied_error(str(path))
if denied:
raise PermissionError(denied)
# Approval-gated paths (e.g. ~/.ssh/config) are not hard-denied
# for interactive tools, but the ACP shim has no human channel
# to confirm the write — fail closed here.
if is_write_approval_required(str(path)):
raise PermissionError(
f"Write denied: '{path}' requires interactive approval "
"and cannot be written through the ACP file bridge."
)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(str(params.get("content") or ""), encoding="utf-8")
response = {
"jsonrpc": "2.0",
"id": message_id,
"result": None,
}
except Exception as exc:
response = _jsonrpc_error(message_id, -32602, str(exc))
else:
response = _jsonrpc_error(
message_id,
-32601,
f"ACP client method '{method}' is not supported by Hermes yet.",
)View on GitHub (pinned to c896c09c42)
Solutions
- Let the agent write to a neutral file, then apply the change to the gated path yourself.
- Make the modification manually through the interactive CLI (hermes), which can surface the approval prompt.
- If the path should not be gated, review the approval-required list configuration — do not bypass the guard for credential-adjacent files.
Example fix
# before — Copilot ACP tries to edit directly write ~/.ssh/config → PermissionError (no approval channel) # after — agent proposes, human applies cp config.draft ~/.ssh/config # operator-run, reviewed
Defensive patterns
Strategy: validation
Validate before calling
# Before routing an ACP write, mirror the guard:
from agent.file_safety import is_write_approval_required, get_write_denied_error
def acp_writable(path: str) -> bool:
return (get_write_denied_error(path) is None
and not is_write_approval_required(path)) Try / catch
try:
handle_fs_write(params)
except PermissionError as e:
if 'requires interactive approval' in str(e):
# write to a draft file instead; apply manually via interactive CLI
... Prevention
- Direct ACP agents to draft files for gated paths; apply changes manually
- Use the interactive CLI when approval-gated writes are needed
- Do not attempt to bypass the approval gate — it protects sensitive configs
When it happens
Trigger: is_write_approval_required(str(path)) returns true for the resolved write target — paths considered sensitive enough to need a human yes/no (SSH config and similar). Reached only after _ensure_path_within_cwd and get_write_denied_error both pass.
Common situations: Copilot ACP agent trying to modify SSH config or other approval-gated files inside the session workspace scope; users expecting the ACP bridge to behave like the interactive CLI's approve-on-write flow.
Related errors
- Path '{resolved}' is outside the session cwd '{root}'.
- 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.
- Copilot ACP {method} failed: {err.get('message') or err}
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/4f4287d6cfd8e7e5.
Report an issue: GitHub.