Skip to content

Commit 8638ca6

Browse files
Skip permission RPC response when resolvedByHook is true
When the runtime resolves a permission request via a permissionRequest hook, it sets resolvedByHook=true on the broadcast event. The SDK broadcast handlers were unconditionally invoking the permission handler and sending an RPC response, causing duplicate/invalid responses. Add a guard in all four SDKs (Node, Python, Go, .NET) to skip the permission handler and RPC response when resolvedByHook is set, while still allowing event subscribers to observe the event. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ac55287 commit 8638ca6

4 files changed

Lines changed: 15 additions & 1 deletion

File tree

dotnet/src/Session.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ private async Task HandleBroadcastEventAsync(SessionEvent sessionEvent)
456456
if (string.IsNullOrEmpty(data.RequestId) || data.PermissionRequest is null)
457457
return;
458458

459+
if (data.ResolvedByHook == true)
460+
return; // Already resolved by a permissionRequest hook; no client action needed.
461+
459462
var handler = _permissionHandler;
460463
if (handler is null)
461464
return; // This client doesn't handle permissions; another client will.

go/session.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,9 @@ func (s *Session) handleBroadcastEvent(event SessionEvent) {
915915
if requestID == nil || event.Data.PermissionRequest == nil {
916916
return
917917
}
918+
if event.Data.ResolvedByHook != nil && *event.Data.ResolvedByHook {
919+
return // Already resolved by a permissionRequest hook; no client action needed.
920+
}
918921
handler := s.getPermissionHandler()
919922
if handler == nil {
920923
return

nodejs/src/session.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,14 @@ export class CopilotSession {
408408
);
409409
}
410410
} else if (event.type === "permission.requested") {
411-
const { requestId, permissionRequest } = event.data as {
411+
const { requestId, permissionRequest, resolvedByHook } = event.data as {
412412
requestId: string;
413413
permissionRequest: PermissionRequest;
414+
resolvedByHook?: boolean;
414415
};
416+
if (resolvedByHook) {
417+
return; // Already resolved by a permissionRequest hook; no client action needed.
418+
}
415419
if (this.permissionHandler) {
416420
void this._executePermissionAndRespond(requestId, permissionRequest);
417421
}

python/copilot/session.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,10 @@ def _handle_broadcast_event(self, event: SessionEvent) -> None:
12241224
if not request_id or not permission_request:
12251225
return
12261226

1227+
resolved_by_hook = getattr(event.data, "resolved_by_hook", None)
1228+
if resolved_by_hook:
1229+
return # Already resolved by a permissionRequest hook; no client action needed.
1230+
12271231
with self._permission_handler_lock:
12281232
perm_handler = self._permission_handler
12291233
if not perm_handler:

0 commit comments

Comments
 (0)