Skip to content

Copilot Chat Agent mode: ToolCallingLoop stop hook intermittently terminates conversations with no response #301795

Description

@Williamleejx

Description

When using Copilot Chat in Agent mode with Claude Agent SDK (claude-opus-4.6), multi-turn conversations are intermittently terminated by the ToolCallingLoop stop hook returning shouldContinue=false with reasons=undefined. This
causes the user to see either "Sorry, no response was returned" or the conversation silently stops — even when the Claude API has successfully returned a valid response.

Environment

  • VS Code: 1.111.0
  • Copilot Chat Extension: 0.39.0 / 0.39.1 (both affected)
  • Connection: VS Code Remote SSH (vscode-server)
  • Model: claude-opus-4.6 (via Claude Copilot Proxy)
  • Copilot SKU: copilot_for_business_seat_quota

Root Cause

The ToolCallingLoop stop hook intermittently returns shouldContinue=false with no reason, prematurely killing the agent loop:

[info] ccreq:0496329b | success | claude-opus-4.6 -> claude-opus-4-6 | 2779ms | [panel/editAgent]
[info] [ToolCallingLoop] Stop hook result: shouldContinue=false, reasons=undefined

Claude returned a valid response, but the stop hook discarded it. The user sees "Sorry, no response was returned."

Behavior Details

  • Intermittent: The stop hook may fire on the first message, then work fine on retry. In one session, it fired twice in a row, then worked normally — same extension host, same version.
  • Not version-specific: Observed on both 0.39.0 and 0.39.1. Downgrading does not help.
  • Agent mode only: The issue only occurs in agent mode ([panel/editAgent]). When requests go through [Claude Copilot Proxy] directly (non-agent mode), they complete successfully with no stop hook interference.
  • First observed: 2026-03-12. Not present in 2026-03-11 logs.

Additional Errors in Logs

  1. Error during execution — a downstream consequence of the stop hook issue. Thrown in wO.handleResultMessage (extension.js:2128:11800) after the loop is prematurely terminated. Observed 9 times in a single session, triggered
    by rate limiting (429), vision API errors (400), and even after successful API responses.
  2. PendingMigrationError: navigator is now a global in nodejs — occurs during extension initialization on every startup. May contribute to instability.
  3. Operation aborted — multiple instances in remoteexthost.log, thrown from x$e.write in the extension.

Expected Behavior

  1. The stop hook should not return shouldContinue=false when Claude has returned a valid response.
  2. If the stop hook decides to terminate, reasons should contain an actionable explanation, not undefined.
  3. Transient API errors (429 rate limiting, 400 vision not enabled) should be handled gracefully — retry or skip, not terminate the entire conversation.

Workaround

Resend the same message. It sometimes succeeds on retry. However, retry suddenly never succeeded again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions