anomalyco / anomalyco/opencode

plugins: private GitHub install fails after codeload 404

Open
#48,133 0 comments 0 reactions 1 assignee View on GitHub

@kitlangton is already working on this.

Since Sep 9, 2026.

2.0
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

  1. Configure a private GitHub repository as a plugin:
    {
      "plugins": ["github:<owner>/<private-plugin>"]
    }
    
  2. Ensure SSH access to the repository is available.
  3. 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.json now depends on pacote@21.5.1.
  • package.json still registers the patch only for pacote@21.5.0.
  • bun.lock resolves pacote@21.5.1.
  • The installed pacote@21.5.1 therefore retains the upstream check:
    if (er.constructor.name.match(/^Http/))
    
    which does not recognise the observed HTTP error object.
  • 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.