Skip to content

Windows Desktop 1.14.39 tries to install @opencode-ai/plugin@local #26003

Closed as not planned

Description

@netics01

Problem

OpenCode Desktop on Windows logs repeated config dependency install failures because it tries to install @opencode-ai/plugin@local.

@opencode-ai/plugin is a valid official package, but local is not a published npm version or dist-tag, so npm resolution fails.

This looks related to #20891, but this report is for an installed official Windows Desktop release, not a locally built preview binary.

Environment

  • OS: Windows 11
  • Client: OpenCode Desktop
  • Desktop executable version: 1.14.39
  • Workspace: normal git repository with an .opencode directory
  • Current project .opencode contents: only .gitignore, empty agents/, empty commands/; no project plugin files and no .opencode/package.json

Observed log

From C:\Users\USER\.local\share\opencode\log\2026-05-06T075806.log:

WARN  2026-05-06T07:58:08 +999ms service=config dir=D:\Github\OpencodeScratch\.opencode error=Cause([Fail(NpmInstallFailedError (cause: @opencode-ai/plugin: No matching version found for @opencode-ai/plugin@local.))]) background dependency install failed

The same warning repeated across several recent startup logs:

2026-05-06T075806.log
2026-05-06T075017.log
2026-05-06T055553.log
2026-05-06T040512.log
2026-05-06T035703.log
2026-05-06T035536.log

Expected

Official Desktop builds should install a published @opencode-ai/plugin version matching the running OpenCode release, or skip pinning to a version when the runtime is treated as local/dev.

They should not try to install @opencode-ai/plugin@local in a released Desktop build.

Investigation / suspected root cause

The config dependency installer adds @opencode-ai/plugin with InstallationVersion unless InstallationLocal is true:

npmSvc.install(dir, {
  add: [
    {
      name: "@opencode-ai/plugin",
      version: InstallationLocal ? undefined : InstallationVersion,
    },
  ],
})

Code reference in current dev:

packages/opencode/src/config/config.ts

InstallationVersion falls back to "local" if the compile-time OPENCODE_VERSION define is absent:

export const InstallationVersion = typeof OPENCODE_VERSION === "string" ? OPENCODE_VERSION : "local"
export const InstallationChannel = typeof OPENCODE_CHANNEL === "string" ? OPENCODE_CHANNEL : "local"
export const InstallationLocal = InstallationChannel === "local"

Code reference:

packages/core/src/installation/version.ts

The standalone Bun CLI build defines both OPENCODE_VERSION and OPENCODE_CHANNEL:

packages/opencode/script/build.ts

But the Node server build used by Desktop appears to define only OPENCODE_CHANNEL, not OPENCODE_VERSION:

define: {
  OPENCODE_MIGRATIONS: JSON.stringify(migrations),
  OPENCODE_CHANNEL: `'${Script.channel}'`,
}

Code reference:

packages/opencode/script/build-node.ts

Desktop imports that Node server build via ../opencode/dist/node:

packages/desktop/electron.vite.config.ts

So the Desktop server bundle may end up with:

  • InstallationVersion === "local"
  • InstallationChannel !== "local"
  • InstallationLocal === false

That combination makes config dependency installation request @opencode-ai/plugin@local.

Why this matters

For workspaces without local plugins this may be a noisy background warning only. For workspaces with local plugins or custom tools that import @opencode-ai/plugin, this can break dependency preparation and lead to confusing plugin loading behavior.

Notes

npm view @opencode-ai/plugin version dist-tags shows latest: 1.14.39, but no local dist-tag.

Activity

  1. netics01 commented on May 6, 2026

    @netics01
    Author

    Additional precise code references from current dev as checked during the report:

    • InstallationVersion fallback to "local":
      export const InstallationVersion = typeof OPENCODE_VERSION === "string" ? OPENCODE_VERSION : "local"
      export const InstallationChannel = typeof OPENCODE_CHANNEL === "string" ? OPENCODE_CHANNEL : "local"
      export const InstallationLocal = InstallationChannel === "local"
    • Config dependency installer pins @opencode-ai/plugin to InstallationVersion unless InstallationLocal:
      const dep = yield* npmSvc
      .install(dir, {
      add: [
      {
      name: "@opencode-ai/plugin",
      version: InstallationLocal ? undefined : InstallationVersion,
      },
      ],
      })
    • TUI config dependency installer has the same version selection logic:
      const deps = yield* Effect.forEach(
      data.dirs,
      (dir) =>
      npm
      .install(dir, {
      add: [
      {
      name: "@opencode-ai/plugin",
      version: InstallationLocal ? undefined : InstallationVersion,
      },
      ],
      })
      .pipe(Effect.forkScoped),
    • Standalone Bun CLI build defines both OPENCODE_VERSION and OPENCODE_CHANNEL:
      define: {
      OPENCODE_VERSION: `'${Script.version}'`,
      OPENCODE_MIGRATIONS: JSON.stringify(migrations),
      OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + workerRelativePath,
      OPENCODE_WORKER_PATH: workerPath,
      OPENCODE_CHANNEL: `'${Script.channel}'`,
      OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "",
    • Node server build used by Desktop defines OPENCODE_CHANNEL but not OPENCODE_VERSION:
      await Bun.build({
      target: "node",
      entrypoints: ["./src/node.ts"],
      outdir: "./dist/node",
      format: "esm",
      sourcemap: "linked",
      external: ["jsonc-parser", "@lydell/node-pty"],
      define: {
      OPENCODE_MIGRATIONS: JSON.stringify(migrations),
      OPENCODE_CHANNEL: `'${Script.channel}'`,
      },
      files: {
      "opencode-web-ui.gen.ts": "",
      },
      })
    • Desktop imports the Node server bundle from ../opencode/dist/node:
      const OPENCODE_SERVER_DIST = "../opencode/dist/node"
      const nodePtyPkg = `@lydell/node-pty-${process.platform}-${process.arch}`
      const sentry =
      process.env.SENTRY_AUTH_TOKEN && process.env.SENTRY_ORG && process.env.SENTRY_PROJECT
      ? sentryVitePlugin({
      authToken: process.env.SENTRY_AUTH_TOKEN,
      org: process.env.SENTRY_ORG,
      project: process.env.SENTRY_PROJECT,
      telemetry: false,
      release: {
      name: process.env.SENTRY_RELEASE ?? process.env.VITE_SENTRY_RELEASE,
      },
      sourcemaps: {
      assets: "./out/renderer/**",
      filesToDeleteAfterUpload: "./out/renderer/**/*.map",
      },
      })
      : false
      export default defineConfig({
      main: {
      define: {
      "import.meta.env.OPENCODE_CHANNEL": JSON.stringify(channel),
      },
      build: {
      rollupOptions: {
      input: { index: "src/main/index.ts" },
      },
      externalizeDeps: { include: [nodePtyPkg] },
      },
      plugins: [
      {
      name: "opencode:node-pty-narrower",
      enforce: "pre",
      resolveId(s) {
      if (s === "@lydell/node-pty") return nodePtyPkg
      },
      },
      {
      name: "opencode:virtual-server-module",
      enforce: "pre",
      resolveId(id) {
      if (id === "virtual:opencode-server") return this.resolve(`${OPENCODE_SERVER_DIST}/node.js`)
      },
  2. assigned and unassigned on May 6, 2026
  3. github-actions commented on Jul 8, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions