Skip to content

Desktop custom tools fail with Bun workspace dependencies and Node ESM resolution #33366

Closed as not planned

Description

@OSmall

Description

OpenCode Desktop v1.17.9 fails to load project-local custom tools in a setup that is valid under the Bun-based OpenCode CLI/runtime expectations documented for custom tools.

There are two related failure modes in Desktop:

  1. .opencode/package.json dependencies using the Bun/npm workspace protocol fail during Desktop background dependency installation with NpmInstallFailedError / Unsupported URL Type "workspace:".
  2. If a custom tool imports a workspace TypeScript package whose package export points at .ts source, Desktop loads it through Node-style ESM resolution and fails on extensionless relative imports such as export * from "./foo", even though Bun and TypeScript moduleResolution: "Bundler" accept this.

This makes Desktop unable to send prompts in projects with local custom tools, while the same tool graph can load under Bun.

Why this appears Desktop-specific

The CLI path runs under Bun, but Desktop starts an Electron utility sidecar and imports the Node-targeted server bundle from dist/node/node.js. The Desktop sidecar also uses the internal Npm/Arborist dependency installer for config/tool/plugin dependencies. That behavior diverges from the docs, which say local plugin/custom-tool dependencies are installed with Bun and show custom tools using Bun APIs.

Minimal reproduction

Create a project with a Bun workspace package and a project-local custom tool:

// package.json
{
  "private": true,
  "type": "module",
  "workspaces": ["packages/*", ".opencode"]
}
// packages/example-core/package.json
{
  "name": "@example/core",
  "private": true,
  "type": "module",
  "exports": {
    ".": "./src/index.ts"
  }
}
// packages/example-core/src/index.ts
export * from "./message"
// packages/example-core/src/message.ts
export const message = "hello"
// .opencode/package.json
{
  "private": true,
  "type": "module",
  "dependencies": {
    "@example/core": "workspace:*",
    "@opencode-ai/plugin": "1.17.9"
  }
}
// .opencode/tools/example.ts
import { tool } from "@opencode-ai/plugin"
import { message } from "@example/core"

export default tool({
  description: "Return a test message",
  args: {},
  async execute() {
    return message
  },
})

Then open this project in OpenCode Desktop and send any prompt.

Actual behavior

Desktop logs show the background dependency install failure:

background dependency install failed ... NpmInstallFailedError ... Unsupported URL Type "workspace:": workspace:*

If the dependency graph is otherwise present, Desktop can then fail loading the package source with Node-style ESM resolution:

prompt_async failed ... Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../packages/example-core/src/message' imported from .../packages/example-core/src/index.ts

The UI only reports a generic failure such as:

Failed to send command
Unexpected server error. Check server logs for details.

Expected behavior

Desktop should either:

  • load project-local TypeScript custom tools with behavior compatible with the Bun CLI/custom-tool documentation, including Bun workspace dependencies and Bun/TypeScript-style resolution, or
  • clearly document that Desktop custom tools must be Node-compatible and cannot use Bun workspace dependencies / Bun-only module resolution, and surface a clear actionable UI error when a tool cannot be loaded.

A project-local custom tool load failure should not make the whole session unable to respond to prompts.

Environment

  • OpenCode Desktop: v1.17.9
  • OpenCode CLI: v1.17.9
  • Bun: 1.3.14
  • macOS arm64

Related issues

Possibly related, but not exact duplicates:

Activity

  1. github-actions commented on Aug 22, 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