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
Multiple times, no matter which model is being used, the plan mode agent has been breaking protocol and running commands which make destructive changes, even when not prompted to do so.
It is sometimes able to make edits in plan mode, and when it isn't, it writes scripts and run it on cli to make edits.
To dig into this, could you share a few more details?
Provider and model(s) you saw this with, e.g. anthropic/claude-sonnet-4.6.
Which tool made the edits in the cases where it edited directly: was it the edit/write/patch tool, or a shell command such as cat > file, sed -i or a script? In v2.0.24 the Plan agent is denied the edit tools for everything outside ~/.opencode/plan/, so a direct edit through those tools would be a separate bug.
Your config: any custom agent/agents or permission settings, and how you entered Plan mode (Tab in the TUI, default_agent, an IDE/ACP client, …).
An example: a share link (/share), a screenshot of the tool calls, or the prompt that led to it.
About the scripts: in v2.0.24 the Plan agent has no rule for shell commands, so they run without asking, and only the Plan mode instructions tell the model not to modify files. Until that changes, you can make Plan ask before running any shell command by adding this to your config:
Edits: Some were done by itself in plan mode; tools: bash, python, git {add,reset,commit}, rm, mv
Config: Default config, no changes were ever made
Prompts that led to edits: "Ok, in main.rs.tmp I fixed it, but, first, I want to "debloat" main.rs and move RbcHelper into it's own file.", "maybe it could be repl.rs", "What else should I move files"
Thanks for the details, @RodrigoAroeira! I was able to reproduce this.
On v2.0.24 with the default config, I started a session in the Plan agent and asked it to move RbcHelper out of main.rs into repl.rs. The model answered with a single shell command that created src/repl.rs, edited and then deleted src/main.rs, and ran git add / git commit. OpenCode ran it without a permission prompt, so the files changed and a commit was created while still in Plan mode.
The cause is that Plan only blocks the file-editing tools (outside ~/.opencode/plan/). It has no rule for shell commands, so those run without asking, and only the Plan mode instructions tell the model not to change anything. Some models ignore those instructions, which is what you saw with bash, python, git, rm and mv. The latest v2 (a67cf4c) behaves the same.
Until this is addressed, you can make Plan ask before every shell command by adding this to your config (e.g. ~/.config/opencode/opencode.json):
The cause looks like the Plan agent's permission set in packages/core/src/plugin/plan.ts: it denies the file-editing tools outside ~/.opencode/plan/, but there is no rule for the shell tool, so shell commands fall through to the agent default (* -> allow). That matches the documented Plan mode behaviour, which says both file edits and bash are ask by default.
Plan: add a shell -> ask rule to the plan agent so read-only exploration still works, but any shell command requires confirmation first. I'll cover it with a test alongside the existing plan plugin suite.
For the record on ordering: I claimed this issue on 2026-10-09T01:17Z and had the branch ready, and #54119 was opened later the same day against dev. That PR was closed because v1 only takes critical fixes and because on v2 the rules live in packages/core/src/plugin/plan.ts with the tool named shell — which is what #54165 does. If @potoior wants to take this over on v2 I am happy to hand the branch over.
The change is one additive rule in the Plan agent's permission set:
Permission.evaluate uses findLast, so with no shell rule every shell command fell through to the agent default (* -> allow) — the Plan system reminder was the only thing stopping a model that mutates files through bash / git / rm. That matches the published agent docs, which describe Plan mode as asking before both file edits and bash.
Verified both ways on the current v2 tip: with only the source hunk reverted the new test reads allow (12 pass / 1 fail), and with the change it reads ask (13 pass / 0 fail). explore is deliberately untouched — other built-in agents keep the * -> allow default, which packages/core/test/agent.test.ts pins.
Same here. Agent created test files and a test npm installation during plan mode. But then said it couldn't remove those because.. it was in plan mode. So it's half aware of the suggestion but happily goes about creating editing and installing in order to get more information.
Which stung more, the rm calls or the git reset it ran in Plan mode?
In Plan mode, deletes and resets should face a check the model cannot overrule. I could show you a simple system merging memory, security and authority.
This is a possible cause in permission.ts. The Plan agent's edit deny does not hold when the global config sets edit: { "*": "ask" } (the default in opencode.jsonc) or edit: { "*": "allow" } — the global rule overrides it.
evaluate uses findLast, so the last matching rule wins. For a file outside the plan directory, both the agent's { edit, *, deny } and the session's { edit, *, ask } match — findLast picks the session's ask, the denied check (evaluate(...).effect === "deny") returns false, and the deny never fires. The edit prompts for approval (or goes straight through under allow).
This breaks any agent-level deny that a matching session/global ask/allow rule overrides — not just edit in Plan mode.
Worked in v1.19.5: configured returned only the agent's permissions, so the agent's deny was the last match. Broken since v2.0.0, when configured started merging session permissions in.
Fix suggestion for someone willing to put in the effort: denied should check whether any matching rule is deny (not just the last match's effect), or agent permissions should be evaluated after session permissions so the agent's deny is the last match.
Someone already tried a fix and was rejected though: #56913
SO if this is the way they want to go, maybe the issue need to be marked as not an issue.
I did see improvement when updating the permissions json to have agent and plan/build specific permissions though - so maybe something for trying? Though would be nice if it was more clear the expected template for certain permission needed to be different.
{
"$schema": "https://opencode.ai/config.json",
// Per-agent overrides — these come LAST in findLast, so they win
"agent": {
"build": {
"permission": {
"edit": { "*": "ask", "<allowed paths>": "allow" },
"write": { "*": "ask", "<allowed paths>": "allow" }
}
},
"plan": {
"permission": {
"edit": { "*": "deny" },
"write": { "*": "deny" }
}
}
},
// Global — applies to every agent
"permission": {
"bash": { /* your bash rules */ },
"read": { /* your read rules */ },
"websearch": "ask",
"webfetch": "ask",
"external_directory": { /* your dir rules */ }
}
}
It even commited in an unwanted change of a git submodule without asking me in plan mode.
IDK guys what the heck you did with 2.x but I'm at the edge of going back to 1.x and trying out DeepSeek Harness at this point.....
Activity
opencode-agent commentedon Oct 8, 2026
Thanks for the report, @RodrigoAroeira!
To dig into this, could you share a few more details?
anthropic/claude-sonnet-4.6.edit/write/patchtool, or a shell command such ascat > file,sed -ior a script? In v2.0.24 the Plan agent is denied the edit tools for everything outside~/.opencode/plan/, so a direct edit through those tools would be a separate bug.agent/agentsorpermissionsettings, and how you entered Plan mode (Tab in the TUI,default_agent, an IDE/ACP client, …)./share), a screenshot of the tool calls, or the prompt that led to it.About the scripts: in v2.0.24 the Plan agent has no rule for shell commands, so they run without asking, and only the Plan mode instructions tell the model not to modify files. Until that changes, you can make Plan ask before running any shell command by adding this to your config:
{ "agent": { "plan": { "permission": { "bash": "ask" } } } }You can reply here with the details, or edit the issue. If you edit it, please also leave a comment saying you've updated it so we know you're done.
Related issues, ordered from most to least likely to match:
RodrigoAroeira commentedon Oct 8, 2026
opencode-agent commentedon Oct 8, 2026
Thanks for the details, @RodrigoAroeira! I was able to reproduce this.
On v2.0.24 with the default config, I started a session in the Plan agent and asked it to move
RbcHelperout ofmain.rsintorepl.rs. The model answered with a single shell command that createdsrc/repl.rs, edited and then deletedsrc/main.rs, and rangit add/git commit. OpenCode ran it without a permission prompt, so the files changed and a commit was created while still in Plan mode.The cause is that Plan only blocks the file-editing tools (outside
~/.opencode/plan/). It has no rule for shell commands, so those run without asking, and only the Plan mode instructions tell the model not to change anything. Some models ignore those instructions, which is what you saw withbash,python,git,rmandmv. The latestv2(a67cf4c) behaves the same.Until this is addressed, you can make Plan ask before every shell command by adding this to your config (e.g.
~/.config/opencode/opencode.json):{ "agent": { "plan": { "permission": { "bash": "ask" } } } }Related: #53530 (v2 Plan mode not stopping edits with ACP models; it also notes the missing shell rule) and #39491 (the same shell behaviour on v1).
argszero commentedon Oct 9, 2026
I'd like to work on this.
The cause looks like the Plan agent's permission set in
packages/core/src/plugin/plan.ts: it denies the file-editing tools outside~/.opencode/plan/, but there is no rule for theshelltool, so shell commands fall through to the agent default (* -> allow). That matches the documented Plan mode behaviour, which says both file edits and bash areaskby default.Plan: add a
shell -> askrule to the plan agent so read-only exploration still works, but any shell command requires confirmation first. I'll cover it with a test alongside the existing plan plugin suite.argszero commentedon Oct 9, 2026
Opened #54165 with the v2 fix.
For the record on ordering: I claimed this issue on 2026-10-09T01:17Z and had the branch ready, and #54119 was opened later the same day against
dev. That PR was closed because v1 only takes critical fixes and because on v2 the rules live inpackages/core/src/plugin/plan.tswith the tool namedshell— which is what #54165 does. If @potoior wants to take this over on v2 I am happy to hand the branch over.The change is one additive rule in the Plan agent's permission set:
Permission.evaluateusesfindLast, so with noshellrule every shell command fell through to the agent default (* -> allow) — the Plan system reminder was the only thing stopping a model that mutates files throughbash/git/rm. That matches the published agent docs, which describe Plan mode as asking before both file edits and bash.Verified both ways on the current
v2tip: with only the source hunk reverted the new test readsallow(12 pass / 1 fail), and with the change it readsask(13 pass / 0 fail).exploreis deliberately untouched — other built-in agents keep the* -> allowdefault, whichpackages/core/test/agent.test.tspins.rtkirill commentedon Oct 13, 2026
same for me in the latest version - v2.0.27
MowlandCodes commentedon Oct 18, 2026
Same for me in the latest version v2.0.32, it uses
cat > "file" << 'TERMINATOR'shell command to achieve it...It even trying to create and apply a patch to the current project even though it fails
VariableVince commentedon Oct 19, 2026
Same here. Agent created test files and a test npm installation during plan mode. But then said it couldn't remove those because.. it was in plan mode. So it's half aware of the suggestion but happily goes about creating editing and installing in order to get more information.
Possibly or partly fixed via #55127?
samvallad33 commentedon Oct 23, 2026
Hi Rodrigo,
Which stung more, the rm calls or the git reset it ran in Plan mode?
In Plan mode, deletes and resets should face a check the model cannot overrule. I could show you a simple system merging memory, security and authority.
Sam
Pheonix7284 commentedon Oct 29, 2026
This is a possible cause in
permission.ts. The Plan agent'seditdeny does not hold when the global config setsedit: { "*": "ask" }(the default inopencode.jsonc) oredit: { "*": "allow" }— the global rule overrides it.The Plan agent sets:
But
configuredmerges session permissions onto the agent's:evaluateusesfindLast, so the last matching rule wins. For a file outside the plan directory, both the agent's{ edit, *, deny }and the session's{ edit, *, ask }match —findLastpicks the session'sask, thedeniedcheck (evaluate(...).effect === "deny") returns false, and the deny never fires. The edit prompts for approval (or goes straight through underallow).This breaks any agent-level
denythat a matching session/globalask/allowrule overrides — not justeditin Plan mode.Worked in v1.19.5:
configuredreturned only the agent's permissions, so the agent's deny was the last match. Broken since v2.0.0, whenconfiguredstarted merging session permissions in.Fix suggestion for someone willing to put in the effort:
deniedshould check whether any matching rule isdeny(not just the last match's effect), or agent permissions should be evaluated after session permissions so the agent's deny is the last match.Someone already tried a fix and was rejected though: #56913
SO if this is the way they want to go, maybe the issue need to be marked as not an issue.
Pheonix7284 commentedon Oct 30, 2026
I did see improvement when updating the permissions json to have agent and plan/build specific permissions though - so maybe something for trying? Though would be nice if it was more clear the expected template for certain permission needed to be different.
dani-nagy commentedon Nov 1, 2026
It even commited in an unwanted change of a git submodule without asking me in plan mode.
IDK guys what the heck you did with 2.x but I'm at the edge of going back to 1.x and trying out DeepSeek Harness at this point.....