Skip to content

SessionClient poll loop keeps retrying after session disposal ("Cannot invoke native session after disposal has started"), leaking memory until heap OOM #5263

Open

Description

@ctenberge-oneid

Describe the bug

A long-running interactive session gets slower and eventually crashes with FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory. On my machine this happens about once a week.

The cause appears to be an orphaned SessionClient poll loop. If a session is closed (for example, on /resume or when switching sessions) while an MCP server's OAuth flow is still running, the native session gets disposed. The JS-side poll loop does not stop, though. It keeps retrying forever, about once per second for each leaked loop:

[ERROR] SessionClient poll loop error (will retry): Error: Cannot invoke native session after disposal has started

Each leaked loop adds another stream of these errors, and heap usage climbs until V8 aborts at the ~4 GB limit.

Affected version

1.0.100 and 1.0.102 (both crashes happened on these builds)

Steps to reproduce the behavior

  1. Configure remote HTTP MCP servers that need OAuth (in my case Confluence and Datadog) and start an interactive session while their tokens are expired or invalid. Both servers return 401, which triggers the OAuth flow.
  2. Close or switch the session (e.g. /resume another session) while the OAuth/MCP reload is still in progress.
  3. Keep the CLI process running. The log fills with SessionClient poll loop error about once per second for each leaked loop, and the process OOMs after a few days.

Here is the log sequence at the moment the loop starts:

[INFO] Closing session <id>
[ERROR] [rust:rmcp::transport::worker] worker quit with fatal: Transport channel closed, when Client(OAuthChallenge { ... status_code: 401 ... })
[WARNING] [rust:mcp_engine::agent_host] HTTP 401 challenge (...) {"server":"confluence","error":"MCP authorization was cancelled"}
[WARNING] [rust:mcp_engine::agent_host] HTTP 401 challenge (...) {"server":"datadog","error":"MCP authorization was cancelled"}
[WARNING] [rust:copilot_runtime::session::mcp::session_host] MCP reload lock still held at disposal; draining the graph without it
[ERROR] [rust:copilot_runtime::shared_api::event_log] Failed to retry MCP servers after OAuth listener registration: {"error":"MCP session host is disposed"}
[ERROR] SessionClient poll loop error (will retry): Error: Cannot invoke native session after disposal has started
... (repeats forever)

Expected behavior

Disposing a session should stop its SessionClient poll loop, or the loop should exit on this error instead of retrying. Leaked loops should not pile up and exhaust the heap.

Additional context


🤖 This issue was posted on behalf of Caleb Tenberge by GitHub Copilot CLI (Claude Opus 5.5/Anthropic).

Activity

  1. added
    area:mcpMCP server configuration, discovery, connectivity, OAuth, policy, and registry
    area:sessionsSession management, resume, history, session picker, and session state
    and removed on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:mcpMCP server configuration, discovery, connectivity, OAuth, policy, and registryarea:sessionsSession management, resume, history, session picker, and session state

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions