Skip to content

fix(server): await plugin activation before listing skills - #51687

Closed
ANSHSINGH050404 wants to merge 1 commit into
anomalyco:v2from
ANSHSINGH050404:skill-list-readiness
Closed

ANSHSINGH050404 wants to merge 1 commit into
anomalyco:v2from
ANSHSINGH050404:skill-list-readiness

Conversation

@ANSHSINGH050404

Copy link
Copy Markdown
Contributor

Summary

GET /api/skill could answer from an empty skill registry on a cold server. Skills are only registered by plugins (ConfigSkillPlugin and plugin-provided skills), and a cold Location activates its plugins asynchronously: PluginSupervisor forks the initial activation, so a location layer finishes building while the registry is still empty. The handler read Skill.list() immediately, so the first SDK skills.list() returned [] and a later call returned the real list.

Plugin.awaitActivation exists precisely for this, and packages/core/src/plugin/service.ts documents the failure mode it prevents: "A cold Location activates its plugins asynchronously, so without the wait an early request observes an empty registry." Session entry points (session/skill.ts, session/prompt.ts, session/command.ts, session/shell.ts) and the integration.list / rpc.call handlers already wait on it. The skill read did not, so it now does too.

Empty is a valid answer for "this project has no skills", which leaves a client with no way to tell "not loaded yet" from "nothing registered" and no readiness signal to wait on. The test pins both halves of the contract: the read does not answer while activation is in flight, and the answer it eventually gives already carries the plugin-registered skill.

Test

packages/server/test/skill.test.ts registers a host plugin gated on a Deferred and holds the release until the first /api/skill request is in flight. Without the fix, that request completes from the empty registry and the assertion that it stayed pending fails; with the fix, it returns the skill the plugin registered on release.

bun test in packages/server: 62 pass, 3 skip, 0 fail.

Note

agent.list has the same missing wait and is tracked separately in #51282, so it is left alone here. This also makes skill.list block for the duration of activation, the same tradeoff integration.list already makes; catalog reads that must stay nonblocking (provider.list, model.list, covered in #36117) are unaffected.

Closes #51680

A cold Location activates its plugins asynchronously, so the first
skill.list on a fresh server could answer from the empty registry and
report no skills at all. Session entry points already wait on
Plugin.awaitActivation for exactly this reason; the HTTP read did not.
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Sep 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant