github / github/copilot-cli

Tool call hangs after extension startup fails

オープン
#4,670 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

area:plugins area:sessions area:tools
主要言語
Shell
スター
11.2k
フォーク
1.9k
平均マージ
14時間 16分
マージ済み PR(30日)
6

説明

Describe the bug

After I resumed a large session, an extension failed inside joinSession() before reporting ready, and its process exited.

The CLI continued to offer the extension's custom tool. I asked the CLI to call it. The CLI started the call, but the handler did not run and the call reported no error. I aborted it after 9 minutes 38 seconds.

This issue concerns cleanup and dispatch after extension startup failure. A separate large-session attachment defect triggered the failure in this run.

Environment
GitHub Copilot CLI 1.0.82
@github/copilot-sdk 1.0.9-preview.2
Node.js v24.18.1
Linux x86_64
Confirmed startup trigger

I traced the installed 1.0.82 app.js bundle. joinSession() sends a session.resume request containing registration options rather than session history. The host still serializes the resident session's full event array while attaching the extension:

  1. handleSessionResumeCore() handles session.resume and calls the host's initializeSession() with replayEvents: false.
  2. The host's initializeSession() ignores that option and passes session.getEvents() to seamHost.initializeSession().
  3. seamHost.initializeSession() calls JSON.stringify(events).

Node.js v24.18.1 rejects JavaScript strings longer than 536,870,888 UTF-16 code units and throws Invalid string length. I estimated each serialized event array's length from its session event log. Extension attachment succeeded below the limit and failed above it.

In the run that reproduced the stale registration, joinSession() failed with Invalid string length. That session's events.jsonl file was about 1.2 GB.

Honoring replayEvents: false would remove this trigger. Registration cleanup must still handle every startup failure.

Reduced extension
import { writeFile } from "node:fs/promises";
import { joinSession } from "@github/copilot-sdk/extension";

await joinSession({
    tools: [{
        name: "stale_tool_probe",
        description: "Verify extension tool lifecycle.",
        parameters: {
            type: "object",
            properties: {},
            additionalProperties: false,
        },
        skipPermission: true,
        handler: async () => {
            await writeFile(
                new URL("handler-ran.marker", import.meta.url),
                "handler ran\n",
            );
            return "handler-ran";
        },
    }],
});
Observed sequence
  1. I stored the reduced extension under ~/.copilot/session-state/<session-id>/extensions/stale-tool-probe/extension.mjs.
  2. I resumed the large session.
  3. joinSession() failed with Invalid string length before the extension reported ready, and the extension process exited.
  4. I asked the CLI to call stale_tool_probe. The CLI started the call instead of rejecting it as an unknown tool.
  5. The call was still pending when I aborted it. handler-ran.marker did not appear.
Expected behavior
  • The CLI offers an extension's registrations only while the extension is ready and connected.
  • Startup failure or process exit removes every registration owned by that extension.
  • A tool call fails promptly if its owning extension is unavailable at dispatch or exits while the call is pending.
Actual behavior
  • The failed extension's tool remained available after its process exited.
  • The call did not reach the handler or report an error.
Related issues

#4590 reports a different session.resume failure involving hook-processor disposal during extension reconnects.

#3856 reports the inverse symptom: Extension tools disappear after a resume.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

joinSession()、handleSessionResumeCore()、initializeSession()、および seamHost.initializeSession() 周辺の拡張機能のライフサイクルから着手し、再現した stale_tool_probe 拡張機能を入口として使用します。プロセスが利用できない間の起動失敗、登録のクリーンアップ、ディスパッチを追跡します。失敗または終了した拡張機能が登録を公開しなくなり、保留中または新規のツール呼び出しがハングせず速やかに失敗するようになれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
javascript, node.js
領域
backend, cli
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
64/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。