anomalyco / anomalyco/opencode
plugins: private GitHub install fails after codeload 404
@kitlangton is already working on this.
Since Sep 9, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
Installing a private GitHub plugin through a github: or SSH package spec fails after pacote resolves the repository over SSH, then receives a 404 from GitHub's unauthenticated codeload tarball endpoint. The expected fallback to an authenticated SSH clone is not applied.
Environment
- opencode version:
0.0.0-beta-19271 - OS: Darwin 25.6.0, arm64
- Terminal: Ghostty (
TERM=xterm-ghostty,COLORTERM=truecolor; captured diagnostics) - Shell:
/bin/zsh(captured diagnostics) - Install/channel: beta
- Active plugins: several local plugins plus one private GitHub package plugin; affected entry redacted as
github:<owner>/<private-plugin>
Reproduction
- Configure a private GitHub repository as a plugin:
{ "plugins": ["github:<owner>/<private-plugin>"] } - Ensure SSH access to the repository is available.
- Start OpenCode and inspect the server plugin status.
The same failure occurs when using an explicit git@github.com:<owner>/<private-plugin>.git source.
Expected Behavior
Pacote should resolve and install the private repository using SSH. If the codeload tarball optimisation returns an HTTP error, installation should fall back to cloning the repository over SSH.
Actual Behavior
The repository is successfully resolved over SSH to a private commit SHA, proving repository authentication works. Pacote then requests an unauthenticated codeload URL and fails permanently on its 404 response:
NpmInstallFailedError
404 Not Found - GET https://codeload.github.com/<owner>/<private-plugin>/tar.gz/<commit>
OpenCode reports:
Server plugin error
Status: failed
Runtime: server
Error: Plugin failed to load
The failure is consistently reproducible.
Additional Context
OpenCode already contains patches/pacote@21.5.0.patch, which broadens pacote's tarball failure handling and falls back to cloning when an HTTP status is at least 400 or the response is not a valid tarball.
However:
packages/util/package.jsonnow depends onpacote@21.5.1.package.jsonstill registers the patch only forpacote@21.5.0.bun.lockresolvespacote@21.5.1.- The installed
pacote@21.5.1therefore retains the upstream check:
which does not recognise the observed HTTP error object.if (er.constructor.name.match(/^Http/)) - The dependency changed in commit
ed3259a9(refactor(plugin): centralize host resolution), while the patch registration was not updated.
A temporary workaround is a local plugin checkout or an SSH hostname alias that prevents pacote from recognising the remote as GitHub and selecting the codeload optimisation.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.