anomalyco / anomalyco/opencode

[Desktop][Windows] npm plugin from config is silently never loaded — no install attempt logged, docs/cache mismatch

Open
#44,367 2 comments 0 reactions 1 assignee View on GitHub

@Hona is already working on this.

Since Aug 23, 2026.

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

Description

Environment

  • App: OpenCode Desktop (@opencode-ai/desktop), server version 1.18.21
  • OS: Windows 11 (win32), Bun available on PATH (bun 1.x via npm global)
  • Plugin: @allansantos-dev/opencode-memory@0.2.0 (public scoped npm package, exports . and ./server, engines.opencode: "^1.18.0")

Summary

An npm plugin declared in opencode.jsonc is silently never loaded: the new session has none of the plugin's tools/hooks, opencode.log shows zero install-attempt or error lines for it, and the documented cache location does not match what the code actually uses. The user only finds out because they notice missing tools — this makes first-run plugin failures undiagnosable.

Evidence

1. Docs and code disagree about the install target
  • Docs (https://opencode.ai/docs/plugins/ — “How plugins are installed”): packages are cached in ~/.cache/opencode/node_modules/
  • Code (packages/core/src/npm.ts, directory(pkg)): installs into ~/.cache/opencode/packages/<sanitized-pkg>/

On this machine ~/.cache/opencode/node_modules/ never existed; nothing ever wrote to it.

2. Even with a correct packages/ layout present, the plugin still doesn’t load

I pre-populated exactly the structure Npm.add() checks:

~/.cache/opencode/packages/@allansantos-dev/opencode-memory/
└── node_modules/@allansantos-dev/opencode-memory/
    ├── package.json   (v0.2.0, exports["."]["import"] = "./dist/index.js")
    └── dist/index.js  (valid ESM bundle)

After an app restart, the session still had none of the plugin’s tools. No new lines appeared in ~/.local/share/opencode/log/opencode.log for that spec.

3. Failures are dropped without visible logging

packages/opencode/src/plugin/loader.ts supports a Report contract (start / missing / error) covering stages install | entry | compatibility | load, but when a candidate fails it is simply excluded from results:

const ready: R[] = []
for (const item of out) if (item.value !== undefined) ready.push(item.value)
return ready

Whatever the caller passes as report either isn’t wired to user-visible logging at default level, or isn’t passed at all by the desktop path — the net effect is silence.

4. Compatibility gate is not the cause here

Server runs 1.18.21; plugin declares engines.opencode: "^1.18.0" → satisfied (semver.satisfies("1.18.21", "^1.18.0") === true). File-based plugins skip this gate entirely, which is consistent with all file:// plugins loading fine on the same install.

Steps to reproduce

  1. Windows 11, OpenCode Desktop.
  2. Add a valid public scoped npm plugin to global config:
    // ~/.config/opencode/opencode.jsonc
    { "plugin": ["@allansantos-dev/opencode-memory"] }
    
  3. Restart the app, start a new session.
  4. Observe: no tools from the plugin; greping opencode.log for the package name yields no install/load/error lines; ~/.cache/opencode/packages/<pkg>/ was not created by the app itself.

Expected

Either the plugin loads, or the startup log contains at least one WARN line naming the plugin and the failing stage (install / entry / compatibility / load) with the underlying error.

Actual

Silent absence. Diagnosis required reading the loader/npm source to learn where artifacts should be, then hand-building them — and even a correct-looking cache didn’t flip the outcome.

Workaround that works reliably

Copy the bundled entry to the global plugins dir (auto-loaded like any local file):

~/.config/opencode/plugins/<name>.js

(and remove the npm specifier from config to avoid double-loading, since file + npm sources load separately per docs).

Related open issues

  • #39543, #40591, #40639 — Desktop/Windows npm-plugin install failures around @opencode-ai/plugin@local (same silent-failure family)
  • #44062 — NpmConfig.load ignores .npmrc when an ancestor has package.json/node_modules (Windows-common)

Happy to provide additional traces/logs from this machine if useful. I’d also gladly contribute a PR: minimal fix would be (a) wiring report.error/report.missing to log.warn in the caller, and (b) updating the docs page to match npm.ts.

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.