You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
core: NpmConfig.load ignores dir/.npmrc when an ancestor has package.json/node_modules (common on Windows) #44062
NpmConfig.load(dir) (packages/core/src/npm-config.ts) can silently ignore the .npmrc in the requested directory on machines where an ancestor directory contains a package.json or node_modules folder. On Windows this is common: the user profile root (C:\Users\<name>) frequently ends up with both from an accidental install, and opencode's own package cache lives under %LOCALAPPDATA%, inside that profile.
What happens
@npmcli/config finds the project prefix by walking up from cwd until it sees a directory containing package.json or node_modules.
For opencode's plugin/package cache dirs (empty on first install), the walk exits the cache and stops at the polluted ancestor.
The requested directory's .npmrc is never read; the ancestor's (or none) is used instead. When the walk stops at the home directory, its .npmrc also collides with the user config and gets dropped entirely ((same as "user" config, ignored)).
NpmConfig.load maps any internal failure to {}, so installs proceed against the default registry with no diagnostic.
Observed on a real machine: probe with cwd = %TEMP%\npmcfg-X containing registry=https://registry.example.test/:
localPrefix: C:\Users\edogu <- home, not cwd
flat.registry: https://registry.npmjs.org/
sources: ... (same as "user" config, ignored)=project ...
The five existing tests in packages/core/test/npm-config.test.ts fail on this machine and pass in CI only because /tmp ancestors are clean there — i.e. CI cannot see this bug class.
Impact
Plugin/skill dependency installs configured through a project or cache-adjacent .npmrc (private registries, mirrors) silently hit the default registry on affected Windows setups.
Proposed direction
Pin the synthetic CLI prefix to the requested directory (argv: [..., "--prefix=" + dir]). loadLocalPrefix() short-circuits on a cli prefix, making "read dir/.npmrc as project config" deterministic regardless of ancestors. This matches what callers already assume (Npm.install passes path: dir to Arborist explicitly).
In v2, npm configuration loading explicitly pins the project prefix to the requested directory, so an ancestor's package.json or node_modules no longer redirects the local .npmrc lookup. This is present in v2.0.0. To get v2: npm i -g @opencode/cli@latest or curl -fsSL https://opencode.ai/v2/install | bash (desktop: update the app). If you still see this on v2, please open a new issue with the details.
Activity
test(core): cover node_modules ancestor anchors and document prefix-p…
neriousy commentedon Oct 19, 2026
In v2, npm configuration loading explicitly pins the project prefix to the requested directory, so an ancestor's package.json or node_modules no longer redirects the local .npmrc lookup. This is present in v2.0.0. To get v2:
npm i -g @opencode/cli@latestorcurl -fsSL https://opencode.ai/v2/install | bash(desktop: update the app). If you still see this on v2, please open a new issue with the details.