anomalyco / anomalyco/opencode

Plugin loader throws TypeError or executes arbitrary named utility exports in legacy plugins

Open
#50,021 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

In packages/opencode/src/plugin/index.ts, getLegacyPlugins iterates over all exported values of a plugin module (Object.values(mod)):

for (const entry of Object.values(mod)) {
  if (seen.has(entry)) continue
  seen.add(entry)
  const plugin = getServerPlugin(entry)
  if (!plugin) throw new TypeError("Plugin export is not a function")
  result.push(plugin)
}

This causes two issues when authoring plugins:

  1. If a plugin file contains export default async function(ctx) { ... } alongside non-function exports (e.g. export const config = { ... } or constants), getServerPlugin returns undefined for non-functions and it throws TypeError: Plugin export is not a function, failing plugin load.
  2. If a plugin exports helper functions (e.g. for unit testing), OpenCode treats every exported function as a plugin initializer and invokes it with (input, load.options), causing unexpected calls or exceptions when the helper expects different arguments.
OpenCode version

1.18.31

Steps to reproduce
  1. Create a plugin file exporting both a default plugin function and a constant:
export const MY_CONFIG = { foo: "bar" }
export default async function(ctx) {
  return {}
}
  1. Run opencode.
  2. Loading fails with TypeError: Plugin export is not a function.
Operating System

Linux

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.

Research direction

Start in packages/opencode/src/plugin/index.ts at getLegacyPlugins and inspect getServerPlugin and the legacy plugin loading path. Reproduce the examples from the issue, then verify that non-plugin exports do not cause loading errors and helper exports are not invoked as plugin initializers.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.