Skip to content

[Bug Report] spawn opencode ENOENT on Windows — OpenCode GUI fails to start after npm global install #54

Description

@BlazeNebula

[Bug Report] spawn opencode ENOENT on Windows — OpenCode GUI fails to start after npm global install

此反馈内容借助 AI Agent 辅助检查和撰写说明。
This issue was researched and drafted with the assistance of an AI Agent.


English Version

Describe the Bug

Clicking the OpenCode icon in the VS Code activity bar shows the error Failed to start OpenCode: spawn opencode ENOENT and the Webview panel fails to load.

To Reproduce

  1. Install OpenCode CLI globally: npm i -g opencode-ai@latest
  2. Verify in terminal: opencode --version → outputs 1.17.0 (OK)
  3. Install OpenCode GUI extension (v0.4.4) in VS Code
  4. Restart VS Code, click the OpenCode icon in the activity bar
  5. The error appears and the panel does not load

Expected Behavior

The OpenCode panel should load and the extension should be able to start the OpenCode CLI server successfully.

Actual Behavior

An error dialog Failed to start OpenCode: spawn opencode ENOENT is shown and the Webview panel remains blank.

Environment

Item Value
Extension OpenCode GUI (tanishqkancharla.opencode-vscode)
Extension Version 0.4.4
VS Code Version ^1.74.0+
OS Windows
OpenCode CLI Version 1.17.0
Installation Method npm i -g opencode-ai@latest

Root Cause

On Windows, npm global installations create a opencode.cmd wrapper (batch file) in %APPDATA%\npm\. This wrapper locates the actual executable at %APPDATA%\npm\node_modules\opencode-ai\bin\opencode.exe. The entry added to the system PATH is opencode.cmd, not opencode.exe itself.

The extension spawns OpenCode CLI via child_process.spawn('opencode', args) in dist/extension.js, but does not pass { shell: true } option. On Windows, Node.js spawn() without shell: true cannot resolve .cmd wrappers, resulting in the ENOENT error.

Verification Results:

Call Result
spawn('opencode', ['--version']) ENOENT
spawn('opencode.cmd', ['--version']) EINVAL (.cmd cannot be spawned directly)
spawn('opencode', ['--version'], { shell: true }) ✅ Outputs 1.17.0
spawn('full-path/opencode.exe', ['--version']) ✅ Outputs 1.17.0

Affected Code

File: dist/extension.js (bundled output; source code in the GitHub repository)

Location ①spawn call inside createOpencodeServer():

const proc = node_child_process.spawn(`opencode`, args, {
    signal: options.signal,
    env: {
      ...process.env,
      OPENCODE_CONFIG_CONTENT: JSON.stringify(options.config ?? {})
    }
    // ⚠️ Missing: shell: process.platform === 'win32'
});

Location ②spawnSync call inside ensureOpencodeCliAvailable():

const lookupResult = child_process.spawnSync(lookupCommand, ["opencode"], {
    encoding: "utf8"
    // This works by accident because where.exe is a real executable,
    // but should also be hardened for consistency
});

Suggested Fix

  1. Add shell: process.platform === 'win32' (or shell: true) to the spawn options in createOpencodeServer()
  2. Consider resolving the real .exe path from the .cmd wrapper on Windows to avoid shell injection risks
  3. In ensureOpencodeCliAvailable(), store the resolved binary path from where/which and reuse it for the actual spawn, rather than only performing an existence check

Workaround

While waiting for an official fix, users can manually add the opencode.exe directory (%APPDATA%\npm\node_modules\opencode-ai\bin\) to the system PATH environment variable, then restart VS Code.


中文版

问题描述 (Describe the Bug)

在 VS Code 中点击活动栏的 OpenCode 图标后,弹出错误提示 Failed to start OpenCode: spawn opencode ENOENT,Webview 面板无法加载。

复现步骤 (To Reproduce)

  1. 通过 npm i -g opencode-ai@latest 全局安装 OpenCode CLI
  2. 在终端中验证安装:opencode --version → 正常输出 1.17.0
  3. 在 VS Code 中安装 OpenCode GUI 扩展 (v0.4.4)
  4. 重启 VS Code,点击左侧活动栏的 OpenCode 图标
  5. 弹出上述错误提示,界面无法加载

预期行为 (Expected Behavior)

OpenCode 面板应正常加载,扩展应能成功启动 OpenCode CLI 服务。

实际行为 (Actual Behavior)

弹出错误对话框 Failed to start OpenCode: spawn opencode ENOENT,Webview 面板空白无法加载。

环境信息 (Environment)

项目
扩展名称 OpenCode GUI (tanishqkancharla.opencode-vscode)
扩展版本 0.4.4
VS Code 版本 ^1.74.0+
操作系统 Windows
OpenCode CLI 版本 1.17.0
安装方式 npm i -g opencode-ai@latest

根因分析 (Root Cause)

在 Windows 上,npm 全局安装的包会在 %APPDATA%\npm\ 目录下生成一个 opencode.cmd 包装器(批处理文件),该包装器负责定位到真正的可执行文件 %APPDATA%\npm\node_modules\opencode-ai\bin\opencode.exe。实际加入系统 PATH 的是 opencode.cmd(而非 opencode.exe 本身)。

扩展在 dist/extension.js 中通过 child_process.spawn('opencode', args) 启动 OpenCode CLI,但未传递 { shell: true } 选项。在 Windows 上,Node.js 的 spawn() 不带 shell: true 时无法解析 .cmd 包装器,导致 ENOENT 错误。

验证数据:

调用方式 结果
spawn('opencode', ['--version']) ENOENT
spawn('opencode.cmd', ['--version']) EINVAL(.cmd 不可直接 spawn)
spawn('opencode', ['--version'], { shell: true }) ✅ 正确输出 1.17.0
spawn('全路径/opencode.exe', ['--version']) ✅ 正确输出 1.17.0

受影响代码 (Affected Code)

文件: dist/extension.js(构建产物,对应源码见 GitHub 仓库)

位置 ①createOpencodeServer() 函数中的 spawn 调用:

const proc = node_child_process.spawn(`opencode`, args, {
    signal: options.signal,
    env: {
      ...process.env,
      OPENCODE_CONFIG_CONTENT: JSON.stringify(options.config ?? {})
    }
    // ⚠️ 缺少 shell: process.platform === 'win32'
});

位置 ②ensureOpencodeCliAvailable() 方法中的 spawnSync 调用:

const lookupResult = child_process.spawnSync(lookupCommand, ["opencode"], {
    encoding: "utf8"
    // 此处因使用 where.exe 而侥幸能工作,但同理建议加固
});

建议修复 (Suggested Fix)

  1. createOpencodeServer()spawn 选项中添加 shell: process.platform === 'win32'(或 shell: true
  2. 考虑在 Windows 上优先解析 .cmd 包装器背后的真实 .exe 路径,以规避 shell 注入风险
  3. ensureOpencodeCliAvailable() 中,将从 where/which 查到的路径记下并复用于后续 spawn,而非仅做存在性检查

临时绕过方案 (Workaround)

在等待官方修复期间,用户可以将 opencode.exe 的直接路径(%APPDATA%\npm\node_modules\opencode-ai\bin\)手动加入系统 PATH 环境变量并重启 VS Code。


Activity

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

Metadata

Metadata

Assignees

No one assigned

    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