anomalyco / anomalyco/opencode

[BUG] Global plugin entry pointing under C:\Program Files\... is silently ignored on Windows (no error, no log, no event)

Open
#49,458 2 comments 0 reactions 1 assignee View on GitHub

@Hona is already working on this.

Since Sep 17, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

Description

On Windows, a global plugin entry whose absolute path lives under C:\Program Files\... is never loaded. Nothing is reported anywhere:

  • not in ~/.local/share/opencode/log/opencode.log, even with --log-level DEBUG --print-logs
  • not as an error event on the GET /event SSE stream
  • the TUI/CLI shows nothing

Copying the exact same files to any user-writable path makes the plugin load normally. So the config is valid and the module is valid — the entry is dropped at load time.

Environment

  • opencode 1.18.31 (installed from npm as opencode-ai, Windows x64 baseline binary)
  • Windows 11 Pro 25H2, build 26200.8457 (kernel 10.0.26200), x64
  • Global config at C:\Users\<user>\.config\opencode\opencode.json

Config

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "C:/Program Files/Clawd on Desk/resources/app.asar.unpacked/hooks/opencode-plugin"
  ]
}

opencode debug config parses and resolves it correctly:

{
  "plugin": [
    "file:///C:/Program%20Files/Clawd%20on%20Desk/resources/app.asar.unpacked/hooks/opencode-plugin"
  ],
  "plugin_origins": [
    {
      "spec": "file:///C:/Program%20Files/Clawd%20on%20Desk/resources/app.asar.unpacked/hooks/opencode-plugin",
      "source": "C:\\Users\\<user>\\.config\\opencode",
      "scope": "global"
    }
  ]
}

opencode debug info also lists the plugin. So resolution works; the entry is dropped later (in loadExternal, most likely).

Steps to reproduce

  1. As administrator, create C:\Program Files\plugtest\index.mjs:
import { appendFileSync } from "node:fs";

export default async () => {
  appendFileSync("C:/plugtest-ran.txt", "loaded " + new Date().toISOString() + "\n");
  return {};
};
  1. Point the global config at it:
{ "$schema": "https://opencode.ai/config.json", "plugin": ["C:/Program Files/plugtest"] }
  1. Run any session, e.g. opencode run --print-logs --log-level DEBUG -m <provider/model> "hi".

  2. C:\plugtest-ran.txt is never created. No mention of the plugin in the logs, no error event.

  3. Copy the same folder to C:\plugtest, change the config entry to C:/plugtest, rerun: the marker file is created immediately.

Test matrix (identical plugin files — only the registered path differs)

Registered plugin path Loaded?
C:/Program Files/Clawd on Desk/resources/app.asar.unpacked/hooks/opencode-plugin (directory) no
C:/Program Files/Clawd on Desk/resources/app.asar.unpacked/hooks/opencode-plugin/index.mjs (explicit file) no
C:\clawd-hooks\opencode-plugin (NTFS junction whose target is the Program Files dir) no
C:/Users/<user>/.config/opencode/clawd-hooks/plugin (copy) yes
C:\oc-plugin-test\opencode-plugin (copy, outside the home directory) yes
C:/Users/<user>/asar-test/app.asar.unpacked/hooks/opencode-plugin (copy; app.asar.unpacked in the path) yes
C:/Users/<user>/clawd test/opencode-plugin (copy; space in the path) yes
trivial control fixture plugin in a writable dir yes

Notes:

  • Spaces in the path are not the problem (clawd test worked).
  • app.asar.unpacked in the path is not the problem.
  • The junction case suggests the check is applied to the resolved real path, not the literal config string.
  • Mixing a working entry and the Program Files entry in the same plugin array in one run: the working one loads, the Program Files one is skipped, still with no error event.

Impact

Clawd on Desk (a desktop pet / session HUD for CLI agents) ships its opencode plugin inside its installed app directory and registers it globally:

C:/Program Files/Clawd on Desk/resources/app.asar.unpacked/hooks/opencode-plugin

That is the default installation path, so every Clawd user on Windows loses the integration silently after upgrading opencode. Debugging is painful because the only visible symptom is "the plugin never runs" — there is no error to search for.

Requests

  1. Don't skip silently. Log a WARN/ERROR for a dropped plugin entry (the report.error callback in the plugin loader currently only publishes a Plugin.Event.Error event), so it shows up in opencode.log and --print-logs.
  2. Surface it in opencode debug config / opencode debug info — e.g. mark an origin as unresolvable/unsupported instead of listing it as if it were loaded.
  3. Support plugin paths in protected/system directories (very common on Windows for app-shipped plugins). If the loader needs write access to the plugin path (for a lockfile / node_modules materialization / bundling step), either avoid that requirement or fail loudly.

Additional observation (low confidence)

A plugin entry at a writable path whose entry file only re-exports the real module is also not loaded:

// C:/Users/<user>/.config/opencode/clawd-shim/index.mjs
export { default } from "file:///C:/Program%20Files/Clawd%20on%20Desk/resources/app.asar.unpacked/hooks/opencode-plugin/index.mjs";

Two variants were tried — the absolute file:// specifier above, and a relative one (../../../../Program Files/Clawd on Desk/.../opencode-plugin/index.mjs), each with a sibling package.json ({"type":"module","main":"index.mjs"}). Both load fine under plain Node (import(){ default: [Function] }) and the default export is the plugin factory, but opencode never runs them. This might indicate the loader resolves/bundles the entry's import graph rather than just the entry — worth checking while fixing the above.

Plugins

opencode-family (shipped by Clawd on Desk) — registered as C:/Program Files/Clawd on Desk/resources/app.asar.unpacked/hooks/opencode-plugin

OpenCode version

1.18.31

Steps to reproduce
  1. As administrator, create C:\Program Files\plugtest\index.mjs:
import { appendFileSync } from "node:fs";

export default async () => {
  appendFileSync("C:/plugtest-ran.txt", "loaded " + new Date().toISOString() + "\n");
  return {};
};
  1. Point the global config at it:
{ "$schema": "https://opencode.ai/config.json", "plugin": ["C:/Program Files/plugtest"] }
  1. Run any session, e.g. opencode run --print-logs --log-level DEBUG -m <provider/model> "hi".

  2. C:\plugtest-ran.txt is never created. No mention of the plugin in the logs, no error event.

  3. Copy the same folder to C:\plugtest, change the config entry to C:/plugtest, rerun: the marker file is created immediately.

Screenshot and/or share link

No response

Operating System

Windows 11 Pro 25H2, build 26200.8457 (kernel 10.0.26200), x64

Terminal

Windows Terminal

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.