Skip to content

Npm.add cache fast-path resolves to broken paths for non-registry specs #24828

@legion-implementer

Description

@legion-implementer

Description

Npm.add in packages/core/src/npm.ts has a cache fast-path that uses npa(pkg).name to resolve the installed package's directory. For non-registry specs (https tarballs, git URLs, github shorthand, file: paths), npa(pkg).name returns undefined and the code falls through to the spec string itself. The resulting path looks like <cache>/node_modules/<full-spec-string>/ which doesn't exist — the package is actually installed at <cache>/node_modules/<actualName>/.

The fresh-install path doesn't have this issue: it uses tree.edgesOut.values().next().value.to.{name,path} which Arborist provides correctly. Only the cache hit path is broken.

Spec npa(pkg).name Cache fast-path
prettier "prettier" works
@scope/pkg@1.0.0 "@scope/pkg" works
https://example.com/foo.tgz undefined broken
git+https://github.com/x/y.git undefined broken
github:owner/repo undefined broken
file:./local.tgz undefined broken

Plugins

This blocks any plugin distribution that doesn't go through the npm registry — private GitHub releases, git URLs, github shorthand, local tarballs.

OpenCode version

Reproduces on current dev (packages/core/src/npm.ts:Npm.add lines 195-207, unchanged since the core package was extracted from opencode).

Steps to reproduce

# Configure opencode with any non-registry plugin spec
echo '{"plugin": ["https://example.com/releases/v1.0.0/example-pkg-1.0.0.tgz"]}' > ~/.config/opencode/opencode.json

# First run installs cleanly via fresh-install path
opencode run "OK"  # works

# Second run hits cache fast-path, fails
opencode run "OK"
# ERROR service=plugin error=ENOENT: no such file or directory, open
#   '<cache>/node_modules/https:/example.com/.../1.0.0.tgz/package.json'

Will open a fix PR shortly.

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions