Node.js: external-tool result-delivery RPC failures are silently swallowed
まだ誰も着手していません。
- #2909 @FOWEPJF255 による — マージされずにクローズ
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 42/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- javascript, node.js
調査の方向性
Start with nodejs/src/session.ts, especially _executeToolAndRespond and _claimExternalTool, then trace the result-submission RPC and its error handling. Add regression coverage for a handler that succeeds while delivery fails, alongside the existing success and handler-error cases. Done means unexpected delivery failures reach the host through a documented diagnostics or error path while cancellation, races, and teardown retain their intended behavior.
索引モデルが issue の本文から書いたものです。
説明
Summary
The Node.js SDK silently swallows an unexpected failure while submitting a completed external-tool result through session.tools.handlePendingToolCall.
The tool handler succeeds, but result submission rejects. _executeToolAndRespond then resolves successfully without surfacing the delivery error. The request has already been removed from the SDK's pending invocation tracking.
If the runtime remains active and has not accepted the result, it can remain waiting for a response. This report does not establish that this code path caused any particular production timeout.
Environment and verification
- OS: Windows x64.
- Node.js: reproduced on both 24.16.0 and 27.0.0-alpha.0.0.0.
- Reproduced with the Node.js SDK bundled in platform package
@github/[email protected]. - The same control flow exists in public SDK main at commit
99d90edf504f824c77dcdf0faa978f4b35848a87. This source comparison is static; the reproduction below was executed against the installed bundle. - The reproduction uses internal SDK seams to isolate result delivery. It starts no runtime or model request and requires no credentials or network access.
Minimal reproduction
Save as repro.mjs in an environment with @github/copilot-sdk installed, then run node --test repro.mjs.
import assert from 'node:assert/strict';
import test from 'node:test';
import { CopilotSession } from '@github/copilot-sdk';
test('unexpected result-delivery errors are surfaced', async () => {
const session = new CopilotSession('repro-session', {});
let handlerCalls = 0;
let responseAttempts = 0;
session._rpc = {
tools: {
handlePendingToolCall: async () => {
responseAttempts++;
throw new Error('simulated result delivery failure');
},
},
};
await assert.rejects(
session._executeToolAndRespond(
'repro-request',
'repro-tool',
'repro-call',
{},
async () => {
handlerCalls++;
return 'done';
},
),
/simulated result delivery failure/,
);
assert.equal(handlerCalls, 1);
assert.equal(responseAttempts, 1);
});
Actual behavior
The test fails with Missing expected rejection.
A separate probe confirms that the handler ran once, result submission was attempted once, and the delivery error was not surfaced. The invocation was no longer present in pendingExternalTools.
On both tested Node.js versions, two positive controls pass and the result-delivery regression fails. The controls cover a successful result submission and a handler exception successfully submitted as an error response.
Expected behavior
An unexpected result-delivery failure should reach the host through an explicit, documented diagnostics or error path rather than silently resolving. Rejecting the internal method is one possible implementation; a structured host diagnostic would also address the observability problem.
Expected cancellation, stale-response rejection, duplicate-client races, and session teardown should retain their intended behavior.
Public source analysis
_executeToolAndRespondcalls_claimExternalToolbefore awaiting the result-submission RPC._claimExternalToolremoves the request frompendingExternalTools.- If result submission rejects, the enclosing catch calls
_claimExternalToolagain. - The second claim returns false because the first claim removed the entry.
- The catch returns without surfacing the delivery failure.
The ownership claim appears intentional for cancellation and race safety, so simply removing it or rerunning the handler would not be a safe fix.
Suggested fix direction
- Separate tool-handler failures from result-delivery failures.
- Keep the single-owner claim and cancellation guarantees.
- Surface unexpected result-delivery failures explicitly instead of routing them through a second ownership claim that suppresses them.
- If result retry is supported, retry only the completed result and document its idempotency guarantees. Do not rerun a tool that may already have produced side effects.
- Add regression coverage for successful delivery, handler failure, unexpected delivery failure, completion races, teardown, and late responses.
Related reports
- #2872 concerns the 1,800-second external-tool timeout and configuration documentation. It is closed, with no public comment or linked fix explaining a supported timeout override.
- #2368 concerns an event dropped before SDK handler entry and is closed as fixed. This report instead starts with a handler that already completed.
- #2509 introduced the request ownership and cancellation behavior and is merged.
- #2425 proposed handler-dispatch diagnostics but was closed without merging.
- 主要言語
- Java
- スター
- 10.7k
- フォーク
- 1.5k
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
github/copilot-sdk のほかの issue
-
Rust: ElicitationRequest drops the tool call id from elicitation.requested再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
github/copilot-sdk#2900 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 84/100
github/copilot-sdk#2876 · コメント 1 件 · リアクション 1 件 ·
-
Python ModelLimits drops max_output_tokens from model metadata再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
github/copilot-sdk#2798 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
github/copilot-sdk#2759 ·
-
docs/AGENTS.md is repo authoring guidance, but everything in docs/ gets published再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンdocumentation
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
github/copilot-sdk#2758 ·
github/copilot-sdk の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
ls1intum/thesis-management#1473 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
LunaDeerMC/Dominion#301 · コメント 1 件 ·
-
[FEATURE] Expose external refresh, node-level translog and warmer stats対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンuntriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
opensearch-project/opensearch-prometheus-exporter#680 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
メンテナーはふだん 2 日以内に返信