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
{{ message }}
Repository navigation
opencode.tools adds the execute / session_move hint even when Code Mode is denied #57711
When Code Mode is turned off with a permission rule ({ "action": "execute", "resource": "*", "effect": "deny" }), Tool.snapshot doesn't build the execute tool (codeModeEnabled = !whollyDisabled("execute", rules)), but the built-in opencode.tools plugin still adds this system part to every context, compaction and generate request:
When you create a worktree outside the current working directory and intend to use it as your primary working directory, consider using execute to call tools.opencode.session_move and make the worktree the session's working directory.
The model is told to use a tool it isn't offered (and tools.opencode.* are Code Mode only, so they aren't reachable either).
Expected: skip the hint when execute is wholly denied for the session's agent.
Related: #48749 (the hint now also reaches compaction and generate requests).
Plugins
Own plugins via the SDK (embedded host); the hint comes from the built-in opencode.tools.
Thanks for the clear report. I was able to reproduce this on 2.0.32 with a simulated model and your permissions (allow *, deny execute). After sending a prompt, the main request offers no execute tool (only glob, grep, patch, question, read, shell, skill, subagent, webfetch, websearch), but its system prompt still contains the execute / tools.opencode.session_move worktree hint.
It still happens on the latest dev (4d59657). The hook in the built-in opencode.tools plugin adds the hint without checking whether execute is denied. The script below reproduces it by checking the outgoing request body.
Related: #48749 (why the hint also reaches compaction and generate requests).
Reproduction script (drive.ts)
// Repro for anomalyco/opencode#57711: with `execute` wholly denied, the request// has no `execute` tool but its system prompt still carries the// `execute` / `tools.opencode.session_move` worktree hint.import{Effect,Stream}from"effect"import{Llm,OpenCodeDriver}from"opencode-drive"constHINT="tools.opencode.session_move"constresults: Array<{index: number;tools: string[];hint: boolean}>=[]consttoolNames=(body: any): string[]=>(body?.tools??[]).map((t: any)=>t?.name??t?.function?.name??"?")exportdefaultOpenCodeDriver.use({
...(process.env.OC_DEV ? {opencode: {dev: process.env.OC_DEV}} : {}),config: {permissions: [{action: "*",resource: "*",effect: "allow"},{action: "execute",resource: "*",effect: "deny"},],},}asany,({ ui, llm }: any)=>Effect.gen(function*(){yield*llm.serve((request: any,index: number)=>{consttext=JSON.stringify(request.body)constentry={ index,tools: toolNames(request.body),hint: text.includes(HINT)}results.push(entry)console.log("REQUEST",JSON.stringify(entry))returnStream.make(Llm.text("ok done"))})yield*ui.submit("hello")yield*ui.waitFor("ok done")// the main agent request is the one that offers tools (skip background requests)constr=results.find((e)=>e.tools.length>0)!console.log(`RESULT execute tool offered: ${r.tools.includes("execute")}; session_move hint in system prompt: ${r.hint}`,)if(!r.tools.includes("execute")&&r.hint)console.log("BUG REPRODUCED")})asEffect.Effect<void,unknown,never>,)
Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.
Activity
opencode-agent commentedon Oct 21, 2026
Thanks for the clear report. I was able to reproduce this on 2.0.32 with a simulated model and your permissions (allow
*, denyexecute). After sending a prompt, the main request offers noexecutetool (only glob, grep, patch, question, read, shell, skill, subagent, webfetch, websearch), but its system prompt still contains theexecute/tools.opencode.session_moveworktree hint.It still happens on the latest
dev(4d59657). The hook in the built-inopencode.toolsplugin adds the hint without checking whetherexecuteis denied. The script below reproduces it by checking the outgoing request body.Related: #48749 (why the hint also reaches compaction and generate requests).
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.