Skip to content

session.rpc.extensions.list() always returns empty array when called from extension hooks #3187

Open

Description

@pavidal-havok

Summary

When an extension calls session.rpc.extensions.list() from inside an onSessionStart or onPreToolUse hook, the returned extensions array is always empty, even when extensions are loaded (including the calling extension itself).

The same RPC works correctly when invoked from the foreground CLI (e.g. via /extensions or the extensions_manage tool), so the data is clearly available to the host — just not to extensions through this API.

Environment

  • Copilot CLI version: 1.0.44-0
  • OS: Windows 11
  • SDK: @github/copilot-sdk/extension

Repro

Minimal extension at .github/extensions/repro/extension.mjs:

import { joinSession } from "@github/copilot-sdk/extension";

const session = await joinSession({
  hooks: {
    onSessionStart: async () => {
      const { extensions } = await session.rpc.extensions.list();
      await session.log(`onSessionStart: ${extensions.length} extension(s)`);
    },
    onPreToolUse: async () => {
      const { extensions } = await session.rpc.extensions.list();
      await session.log(`onPreToolUse: ${extensions.length} extension(s)`);
      return { permissionDecision: "allow" };
    },
  },
  tools: [],
});

Start a Copilot CLI session in the repo and trigger any tool call.

Expected

The logged count is ≥ 1 (at least the calling extension itself, plus any user-source extensions installed in ~/.copilot/extensions/).

Actual

The logged count is always 0, in both onSessionStart and onPreToolUse. No error is thrown; the call resolves successfully with an empty list.

Impact

This API is the only documented way for an extension to discover its peers. Any extension that needs to coordinate with another extension is broken — for example, a project-level guard extension that should refuse to operate unless a specific user-level companion extension (e.g. an auth/policy plugin) is also installed and running cannot make that determination.

Notes

  • The sibling RPCs extensions.enable / extensions.disable / extensions.reload throw "Extensions not available" in failure modes. extensions.list returning a successful-looking empty array instead of erroring made this much harder to diagnose — at minimum, the failure mode should be consistent (a thrown error rather than a misleading empty result) so callers can tell "no peers" apart from "I can't see them".

Activity

  1. added
    area:pluginsPlugin system, marketplace, hooks, skills, extensions, and custom agents
    on May 7, 2026
  2. added theissue type on May 7, 2026
  3. patniko commented on Oct 26, 2026

    @patniko
    Collaborator

    Thanks for the report. We've shipped fixes in this area since this was filed (most recently in Copilot CLI v1.0.63), and we believe this may now be resolved. Could you retest on the latest release (Copilot CLI v1.0.103) and let us know whether you still see it? If we don't hear back in a couple of weeks, we may close this issue — you can always reopen it.

    Triaged as part of a Copilot SDK backlog review, with help from GitHub Copilot.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:pluginsPlugin system, marketplace, hooks, skills, extensions, and custom agentsmore-info-needed

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions