github / github/copilot-cli

Tool call hangs after extension startup fails

未关闭
#4,670 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

area:plugins area:sessions area:tools
主要语言
Shell
星标
11.2k
派生
1.9k
平均合并
14 小时 16 分钟
30 天内合并 PR
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. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 joinSession()、handleSessionResumeCore()、initializeSession() 和 seamHost.initializeSession() 周围的扩展生命周期入手,以复现的 stale_tool_probe 扩展作为切入点。在进程不可用期间,跟踪启动失败、注册清理和 dispatch。完成标准是:失败或已退出的扩展不再暴露注册信息,待处理或新的工具调用会及时失败,而不是一直挂起。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, node.js
领域
backend, cli
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
活跃
描述清晰度
基本清楚
新手友好度
64/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。