Repository navigation
[BUG] Custom providers fail on Desktop (Electron) with ProviderInitError — ESM directory import bug in resolveEntryPoint #31909
Description
Activity
I just noticed this issue was already assigned. I should have checked that before opening the PR, and I’ll make sure to do that in the future.
Sorry for the miss. Happy to defer to the assigned maintainer and close the PR if it conflicts with planned work. If useful, the PR is tested and can also serve as a reference implementation.
Reacted by Toby HendersonHi @hereswilson I think it's okay as @StarpTech was automatically assigned
Thanks for the PR. This is causing a lot of issues for our users of the OpenCode Desktop would be good for them not to have to run the patch.Update — the affected code has moved, but the bug is still present on
dev.Since this was filed,
provider.tswas refactored:resolveEntryPointis no longer inpackages/opencode/src/provider/provider.ts. Provider now resolves entrypoints viaNpm.add(...)and readsitem.entrypoint. The resolution logic itself was relocated topackages/core/src/npm.ts.The bug came along with it unchanged. Current
dev,packages/core/src/npm.ts:53:entrypoint = typeof Bun !== "undefined" ? import.meta.resolve(name, dir) : import.meta.resolve(dir)
Same asymmetry as originally reported: the Bun branch uses the two-arg
import.meta.resolve(name, dir), while the Node branch uses the one-argimport.meta.resolve(dir), which resolves to the package directory URL and throwsERR_UNSUPPORTED_DIR_IMPORTunder Node/Electron. The caller (Npm.add) passes the package directory in asdir, so the broken path is still reached and the original repro still applies on Desktop.The proposed fix still holds — it just needs to target the new file. Using the two-arg form on both paths (
import.meta.resolve(name, dir)) resolves the package export correctly on both Bun and Node 20.6+.Note that #32060 ("fix(core): resolve npm provider entrypoints", Closes #31909) covers this but is still open / unmerged, so anyone hitting this on
devshould look atpackages/core/src/npm.tsrather than the oldprovider.tspath.The community fix #32060 was auto-closed by the stale-PR cleanup before review, and the affected code has since moved to
packages/core/src/npm.ts(as @holytshirt noted above). I've opened #44722 — a fresh implementation against the current layout: on Node, resolve the entry from the installed manifest (exports→module→main→index.js, with acreateRequirefallback) instead of importing the package directory. Verified in real Node 22: the old path reproducesERR_UNSUPPORTED_DIR_IMPORT, the new path loads and initializes the provider.Until a fix lands, a cache-independent workaround for Desktop users: point the provider's
npmfield at the installed entry file via afile://URL (OpenCode passes those straight toimport()), e.g. install the provider package anywhere with npm and usefile:///abs/path/node_modules/<pkg>/dist/index.mjs.Reacted by Toby Henderson and kuma- added a commit that references this issue
on Aug 24, 2026
Bug Report: Custom providers fail on Desktop (Electron) with
ProviderInitErrordue to ESM directory importDescription
Custom npm providers that work perfectly on the CLI (Bun) fail immediately on OpenCode Desktop (Electron/Node.js) with
ProviderInitError. The error is caused by a one-argument vs two-argument difference inresolveEntryPointbetween the Bun and Node code paths.Environment
@my/opencode-ai-gateway-stuff(ESM package with"type": "module")Root Cause
In
packages/opencode/src/provider/provider.ts, theresolveEntryPointfunction has an asymmetry between Bun and Node:Bun path (
import.meta.resolve(name, dir)): Correctly resolves the package name relative to the directory, returning the actual entry file (e.g.,file:///.../<pkg>/dist/index.js).Node path (
import.meta.resolve(dir)): Simply converts the directory path to afile://URL without resolving the package entry point. Returnsfile:///.../<pkg-dir>(a directory URL).Later in
resolveSDK:Node.js ESM does not support
import()of a directory URL — it always fails withERR_UNSUPPORTED_DIR_IMPORT, regardless ofpackage.jsonmain/exportsfields or the presence ofindex.js.Proposed Fix
Change the Node path to use two-argument
import.meta.resolve(supported since Node 20.6+):Or simply:
Both Bun and Node 20.6+ support the two-argument form. Since the Desktop app bundles Node 24.15.0, this is safe.
Steps to Reproduce
"type": "module"and anexportsfield pointing to./dist/index.jsopencode.json:{ "provider": { "my-provider": { "npm": "my-custom-provider-package", "options": { "baseURL": "https://example.com" }, "models": { "my-model": { "name": "My Model" } } } } }ProviderInitError❌Debug Evidence
From server logs (
opencode.log):The error repeats on every retry — the provider never initializes.
Verified by reproducing the exact Desktop flow in Node:
Additional Context
ProviderInitErrorwraps the cause but never surfaces it to the user (see Session error path dropscauseand stack fromProviderInitError, hiding root cause #24430, Provider packages silently fail to install via corporate npm registries — ProviderInitError hides real cause #30069)ignoreScripts: trueinNpm.add's arborist config means packages cannot self-patch viapostinstallWorkaround
Until this is fixed, custom provider packages can work around the issue by having users run a script that replaces the package directory with a shim file:
Related Issues
causeand stack fromProviderInitError, hiding root cause #24430 — ProviderInitError hides cause