Skip to content

plugins: exact-spec install succeeds but TUI reports "Invalid V2 TUI plugin module" - non-exact specs fail reconciliation and the runtime package tree is never materialized #58045

Closed as duplicate

Description

@rudy500

Summary

Two related defects in the v2 plugin pipeline compound so that a successfully
installed TUI plugin never loads, and the TUI masks the real cause with the
generic Invalid V2 TUI plugin module error:

  1. OpenCode's vendored npm resolution (prepare stage) fails with
    NpmInstallFailedError for tag/range specs (bare package name, @latest,
    ^x.y.z ranges in the config-root package.json) on a plugin whose peer
    dependency graph is resolvable — opencode plugin add <name>@<exact-version>
    succeeds with the identical release.
  2. When the configured cli.json spec is a pinned version ([email protected]) but
    reconciliation keeps failing, no runtime package tree is materialized for
    that spec key, and the failed import is surfaced as
    Invalid V2 TUI plugin module: <name>@<version> with no underlying error,
    so it looks like a plugin-authoring problem when it is not.

Environment

  • opencode version: v2.1.2 (channel: latest)
  • OS: Windows 11 (10.0.26300), win32 x64
  • Terminal: xterm-256color
  • Shell: pwsh 7 / cmd.exe
  • Install/channel: latest release, shared background service
  • Active plugins: opencode-subagent-statusline (loads fine), [email protected] (fails), one local TUI plugin file under ~/.config/opencode/tui-plugins/

Reproduction

  1. Configure a TUI plugin in cli.json: {"plugins": ["[email protected]"]}.
  2. opencode plugin add opencode-sdd-engram-manage (bare/tag spec) → fails 100% of the time with
    NpmInstallFailedError (vendored @npmcli/arborist: unable to resolve dependency tree).
  3. opencode plugin add [email protected] (exact spec) → succeeds, writing a complete install
    (plugin + all 5 peers) to ~/.cache/opencode/npm/[email protected]/<generation>/.
  4. Start the TUI: the plugins list shows Status: failed — Invalid V2 TUI plugin module: [email protected].
  5. Observe the cache state:
    • ~/.cache/opencode/packages/[email protected]/ — does not exist
    • ~/.cache/opencode/packages/opencode-sdd-engram-manage@latest/ — complete tree (unused; key does not match the cli.json spec)
    • ~/.config/opencode/node_modules/opencode-sdd-engram-manage/ — module present, peer deps missing
      (plain node import throws ERR_MODULE_NOT_FOUND: Cannot find package '@opentui/solid')
  6. Logs (~/.local/share/opencode/log/opencode.log): repeated
    plugin operation failed ... error=NpmInstallFailedError target=opencode-sdd-engram-manage stage=prepare
    on every TUI/startup preparation.

The module itself is healthy: importing the complete npm-cache generation tree
under node 24 (import plugin dist/tui.js) succeeds, and the default export has
the expected TUI plugin shape ({ id, tui }).

Expected Behavior

  • Tag/range plugin specs should reconcile like exact specs when the peer graph is resolvable (plain npm 11/12 resolves the same graph in ~16 s).
  • After a successful opencode plugin add [email protected], the TUI runtime should have a working install for the configured spec — or reuse the complete generation — instead of failing to load.
  • A failed plugin-module load should surface the underlying cause (e.g. ERR_MODULE_NOT_FOUND: '@opentui/solid') instead of the generic Invalid V2 TUI plugin module message, which points plugin authors at the wrong layer.

Actual Behavior

Plugin marked failed with Invalid V2 TUI plugin module: [email protected];
no error chain reaches the UI or the log; the complete install created by
plugin add sits unused because its cache key does not match the configured
spec, and no runtime tree exists under the pinned key.

Additional Context

  • Plugin: [email protected] (latest published version). Peers:
    @opencode-ai/plugin >=1.17.11, @opentui/core|keymap|solid >=0.4.2 <1, solid-js 1.9.12.
  • Workaround confirmed by hand: copy the complete packages/…@latest tree (or the
    completed npm cache generation) to packages/[email protected],
    then run plain npm install in ~/.config/opencode so the config-root project is
    consistent — after that, module imports succeed and the plugin prepares without
    NpmInstallFailedError warnings.
  • Frequency: deterministic, reproduced on every TUI start and every bare/tag
    plugin add across multiple sessions and days.

Activity

  1. opencode-agent commented on Oct 22, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed write-up! I think this is a duplicate of #50080, which you've already confirmed on 2.1.2 there. It covers the same package failing the same way: a bare, @latest or range spec fails in Npm.reify with unable to resolve dependency tree and shows an empty NpmInstallFailedError in the logs, while @1.7.0 installs fine.

    About the Invalid V2 TUI plugin module part: in the 2.1.2 code (packages/tui/src/plugin/context.tsx), the plugin module is imported directly (Host.load → importModule). A missing @opentui/solid would make that import fail with ERR_MODULE_NOT_FOUND, and you would see that error instead of this one. Invalid V2 TUI plugin module is only thrown after the module has loaded, when its default export is not a V2 plugin, i.e. { id: string, setup: function }. You mentioned the default export is { id, tui }, which is the V1 TUI plugin shape, so I believe the plugin itself needs a V2 setup entry point before it can load under V2. Missing peers in the config-root node_modules are a separate problem.

    Possible duplicates and related issues, ordered from most to least likely:

    The bot will close this issue as a duplicate of #50080 in 1 day unless you reply explaining how your problem is different, for example if the plugin's default export really is { id, setup } and it still fails with this message.

  2. opencode-agent commented on Oct 23, 2026

    @opencode-agent
    Contributor

    Closing this as a duplicate of #50080, since there hasn't been a reply in the past day explaining how it differs. #50080 covers the same failure. When opencode-sdd-engram-manage is given as a bare name, @latest or a range, the install fails with NpmInstallFailedError (unable to resolve dependency tree at Npm.reify), while @1.7.0 installs fine. You've already confirmed it there on 2.1.2, so please follow that issue for updates.

    About the Invalid V2 TUI plugin module error: that message only appears after the module has loaded and its default export turns out not to be { id, setup }. A V1-style { id, tui } export triggers it, as discussed in #52766 and #48365. If the plugin does export a V2 setup and still fails with this message, reply here and we can reopen. Thanks for the thorough report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions