You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When configuring agent-level permissions with absolute path patterns, external_directory works correctly but edit silently fails to match because they use different path formats internally.
Using absolute paths seems like the wrong choice here, in my opinion it would likely be better to regain consistency by allowing relative paths in external_directory.
in my experience, relative paths are bit tricky to manage.
one of my pattern of using OpenCode is running opencode serve in one place and have it running, and run opencode attach to start a client - this is so that I am not starting an OpenCode server everytime which takes more resources on my machine and has a relatively slow startup time.
however, what I have observed is that the "working directory" is based on where opencode serve (/path/A) is started instead of where opencode attach is started (/path/B, /path/C). this has been bugging me for a while.
@fluency03 Typically, I have multiple copies of any given git repository located at different paths and run individual instances of OpenCode in each one simultaneously. If they had to share absolute paths in the permissions in the project-local settings then that would plainly run into problems.
I decided to run opencode serve in one place, have it running, and run opencode attach to start different clients at different places because:
I do see a much faster start up time of the UI comparing to starting a server everytime (plain opencode) especially some of the MCP servers can be heavy;
(please correct me if I am wrong) and I think single server means single set of MCPs running, whereas multiple server means multiple set of MCPs running -> this can be expensive in CPU and memory usage on my machine;
imagine you have 5 servers running, if each server has 3 MCPs enabled, that's already 15 MCP processes running...
I am not even running opencode attach for the same projects in different copies. I am running multiple clients for all of my work across Q&A, multiple different projects, etc, in order to gain the fast start up time and low CPU/memory.
and specifically, I have lots of use cases where I just need to do some investigation or document review - these tasks are not bound to any specific git repository;
Regarding share absolute paths in the permissions, i'd like to write some of the intermediate content of aubagents and thinking processes of the agent into files so that I can review them later. And I'd prefer to use /tmp. I think it should be ok to share permissions to /tmp or a specific directly of /tmp. And on top of that, I am only giving /tmp/some-dir in the custom agent config, not on the top level of OpenCode.
and regardless, there is an inconsistency between how path is recognized in external_directory vs. edit which can be confusing and it's not documented.
The globbing can simply happen against the relative path OR the absolute path as a function of whether or not the glob pattern looks like a relative path or an absolute path itself.
Currently all "edit" patterns look like relative paths, or they would never match anything.
There is no reason not to match patterns (added in the future) that look like absolute paths (aka, the pattern starts with '/' on linux, or 'C://' or whatever on Windows) against the absolute filepath.
On top of that I think we really should use proper globbing. Having a * match anything even ../ is unacceptable.
The only way to avoid leaking personal data to external providers (such as internal folder structure, user names, etc') is by always using relative paths. Any tool that returns an absolute path to the AI model is leaking private data.
@CarloWood - the read and write tools seem to return the absolute path for the files, leaking the information back to the models. Your environment variables circumvent that? How?
This is still very much alive on opencode 1.17.20 (2026-07-21), on a real project — not just the synthetic repro. Auto-closed by the 60-day stale bot with state_reason: not_planned, but nothing was actually fixed.
Reproduction, from ~/.local/share/opencode/log/opencode.log:
The /tmp/opencode/** rule never matches because (per the source referenced in this issue) external_directory always checks against path.join(dir, "*") — a fixed single-star suffix — not the actual file path. Since the specific allow rule can't match, it falls through to the "*": "ask" catch-all, and since the subagent is headless, unresolved ask degrades to deny. Same root cause as #14445 and the general glob-matching issue in #22465.
Workaround that unblocked us: add an extra literal-single-star entry alongside the globstar one:
Reopening would help — this is a genuine footgun for anyone using headless/subagent review pipelines with external_directory rules, not resolved by the closure.
Activity
github-actions commentedon Mar 30, 2026
This issue might be a duplicate of existing issues. Please check:
editpermission check passes a relative path (e.g.workspace/projects/project6/test.pywithout a leading/), which fails to match absolute-path rules like/workspace/projects/**. The logs in that issue even showpattern=workspace/projects/project6/test.pymatching against**(deny) instead of the intended absolute-path rule — identical to the behavior reported here.ariane-emory commentedon Mar 30, 2026
Using absolute paths seems like the wrong choice here, in my opinion it would likely be better to regain consistency by allowing relative paths in
external_directory.fluency03 commentedon Mar 30, 2026
in my experience, relative paths are bit tricky to manage.
one of my pattern of using OpenCode is running
opencode servein one place and have it running, and runopencode attachto start a client - this is so that I am not starting an OpenCode server everytime which takes more resources on my machine and has a relatively slow startup time.however, what I have observed is that the "working directory" is based on where
opencode serve(/path/A) is started instead of whereopencode attachis started (/path/B,/path/C). this has been bugging me for a while.ariane-emory commentedon Mar 30, 2026
@fluency03 Typically, I have multiple copies of any given git repository located at different paths and run individual instances of OpenCode in each one simultaneously. If they had to share absolute paths in the permissions in the project-local settings then that would plainly run into problems.
fluency03 commentedon Mar 30, 2026
@ariane-emory I do see the rational of that.
But in my case
opencode servein one place, have it running, and runopencode attachto start different clients at different places because:opencode) especially some of the MCP servers can be heavy;opencode attachfor the same projects in different copies. I am running multiple clients for all of my work across Q&A, multiple different projects, etc, in order to gain the fast start up time and low CPU/memory.share absolute paths in the permissions, i'd like to write some of the intermediate content of aubagents and thinking processes of the agent into files so that I can review them later. And I'd prefer to use/tmp. I think it should be ok to share permissions to/tmpor a specific directly of/tmp. And on top of that, I am only giving/tmp/some-dirin the custom agent config, not on the top level of OpenCode.and regardless, there is an inconsistency between how path is recognized in
external_directoryvs.editwhich can be confusing and it's not documented.thanks!
CarloWood commentedon Apr 14, 2026
The globbing can simply happen against the relative path OR the absolute path as a function of whether or not the glob pattern looks like a relative path or an absolute path itself.
Currently all "edit" patterns look like relative paths, or they would never match anything.
There is no reason not to match patterns (added in the future) that look like absolute paths (aka, the pattern starts with '/' on linux, or 'C://' or whatever on Windows) against the absolute filepath.
On top of that I think we really should use proper globbing. Having a
*match anything even../is unacceptable.boazsegev commentedon May 8, 2026
The only way to avoid leaking personal data to external providers (such as internal folder structure, user names, etc') is by always using relative paths. Any tool that returns an absolute path to the AI model is leaking private data.
CarloWood commentedon May 8, 2026
@boazsegev I use environment variables for all my absolute paths, also in the opencode.json - that way you don't give anyway anything.
boazsegev commentedon May 8, 2026
@CarloWood - the
readandwritetools seem to return the absolute path for the files, leaking the information back to the models. Your environment variables circumvent that? How?github-actions commentedon Jul 9, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
MataM15 commentedon Jul 21, 2026
This is still very much alive on opencode 1.17.20 (2026-07-21), on a real project — not just the synthetic repro. Auto-closed by the 60-day stale bot with
state_reason: not_planned, but nothing was actually fixed.Reproduction, from
~/.local/share/opencode/log/opencode.log:Config (
~/.config/opencode/opencode.json):Headless review subagents (
mode: subagent, no interactive prompt available) tried to read a diff file written to/tmp/opencode/<lineage>.diff. Log:The
/tmp/opencode/**rule never matches because (per the source referenced in this issue)external_directoryalways checks againstpath.join(dir, "*")— a fixed single-star suffix — not the actual file path. Since the specific allow rule can't match, it falls through to the"*": "ask"catch-all, and since the subagent is headless, unresolvedaskdegrades todeny. Same root cause as #14445 and the general glob-matching issue in #22465.Workaround that unblocked us: add an extra literal-single-star entry alongside the globstar one:
Reopening would help — this is a genuine footgun for anyone using headless/subagent review pipelines with external_directory rules, not resolved by the closure.