Skip to content

[Bug]agent.list returns only built-in agents right after server start because it does not wait for plugin activation #51282

Description

@KnifeOfLife

Description

agent.list returns only built-in agents right after server start because it does not wait for plugin activation

What happens

A plugin that registers agents through the v2 plugin API (setup -> ctx.agent.transform) is missing from GET /agent when a client asks right after the server comes up. The same request succeeds once plugin activation has finished. Session-facing routes already handle this correctly because they wait for activation; the agent list route does not.

How to reproduce

  1. Register an external npm plugin that adds a primary agent during setup(). I used oh-my-opencode-slim 2.2.24 ("plugins": ["oh-my-opencode-slim@latest"]), which registers an orchestrator agent via agent.transform and sets it as the default agent.
  2. Start opencode serve (OpenChamber launches it the same way).
  3. Immediately fetch the agent list (GET /agent).
  4. The response contains only built-in agents. In my case build and plan, since I disable the explore and general agents in config.
  5. A few seconds later the same request includes the plugin agents. Starting a session also makes them show up, because session entry points wait.

Why it happens

  • External package plugins load asynchronously after the HTTP server is already serving. The supervisor activates local plugins first and resolves package installs in the background (packages/core/src/plugin/supervisor.ts, see the comment "Activate everything available locally before waiting on missing package installs"). Loading runs npm.add() first, then imports the module and runs setup().
  • The agent.list handler reads the registry directly. packages/server/src/handlers/agent.ts calls Agent.Service.list() and does not wait for activation.
  • Session entry points do wait. yield* Plugin.awaitActivation runs in packages/core/src/session/prompt.ts, and the same in command, shell and skill entry points. The comment on Plugin.awaitActivation in packages/core/src/plugin/service.ts describes this exact hazard: "A cold Location activates its plugins asynchronously, so without the wait an early request observes an empty registry and admits or fails work the plugins would have shaped."
  • The events that could let clients self-correct do not help at startup. agent.updated and plugin.updated are ephemeral, and the event stream contract states events during disconnection are missed. A client that connects after activation never learns the registry changed.

Impact

Any client that reads the agent list at startup (web UIs, IDE extensions, scripts) shows an incomplete list until something else triggers a refetch. In OpenChamber this means the composer dropdown only offers build and plan after every restart until a session is opened.

Suggested fix

Make agent.list wait for Plugin.awaitActivation, matching what the session entry points already do. It may be worth checking whether command.list and skill.list share the same shape. Alternatively, expose a readiness signal clients can wait on before their first catalog read.

Environment

  • opencode v2.0.16, Windows 11
  • plugin: oh-my-opencode-slim 2.2.24 (v2 promise plugin shape, { id, setup })

Plugins

oh-my-opencode-slim 2.2.24

OpenCode version

v2.0.16

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

Windows 11

Terminal

No response

Activity

  1. github-actions commented on Sep 25, 2026

    @github-actions
    Contributor

    This issue might be related to existing issues. Please check:

  2. remorses commented on Oct 7, 2026

    @remorses
    Contributor

    Same race on 2.0.19, but it is not only at server start: it also happens when an idle location is evicted and then cold-boots again. It also hits plain ~/.config/opencode/agent/*.md agents (loaded by the internal config-agent plugin), no npm plugin needed.

    Workaround: call integration.list first, it awaits Plugin.awaitActivation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions