Skip to content

Auto-resume retries reuse the same broken pooled CLI process after a transport failure #2879

Description

@matthewlhouse

Summary

GitHub Copilot Desktop detects that a session's bundled copilot.exe --server --stdio transport has failed and starts its automatic resume flow, but every retry is routed back to the same known-broken pooled CLI process because it is still reference-counted.

The app retries three times, each attempt fails against the same closed pipe, and the session is marked interrupted. Later session-creation attempts for the same working directory also reuse the broken pool entry and fail. The session only recovered after another active CLI pool process became available and a new message caused the session to be resumed from disk.

This appears to be a Desktop CLI-pool invalidation/replacement bug rather than a missing retry mechanism: retries exist, but they do not replace the failed worker.

Environment

  • GitHub Copilot Desktop: 1.1.8
  • Bundled Copilot CLI: 1.0.79-9
  • OS: Windows 11, build 10.0.26200, x64
  • CLI launch form: copilot.exe --server --stdio --no-auto-update
  • Session type: long-running local project session

Observed sequence

The worker failure occurred during a high-concurrency review fan-out, but the recovery defect should apply to any transport failure while the pooled process still has references.

  1. At 2026-08-14T19:29:59Z, the session launched 16 synchronous subagent tasks.

  2. At 19:30:12Z, the CLI session event log stopped abruptly mid-flight. There was no terminal session event or completed subagent result.

  3. At 19:31:02Z, Desktop's liveness probe correctly detected the failed transport:

    session liveness probe completed ... status="failed"
    failure_kind="transport_failure"
    error="The pipe is being closed. (os error 232)"
    
    session liveness probe failed; attempting auto-resume
    
  4. Desktop then stopped the SDK event loop and attempted to resume, but the CLI pool repeatedly chose the same broken process:

    CLI unresponsive but still in use; reusing existing process
    existing_ref_count=2
    
  5. All retries targeted that same pool entry:

    resume_session failed ... (retry 1/3), retrying in 1s:
    The pipe is being closed. (os error 232)
    
    resume_session failed ... (retry 2/3), retrying in 2s:
    The pipe is being closed. (os error 232)
    
    resume_session failed ... (retry 3/3), retrying in 4s:
    The pipe is being closed. (os error 232)
    
  6. Desktop finally stopped retrying:

    session liveness probe auto-resume failed; marking session as interrupted
    
  7. New session attempts for the same working directory continued selecting the same stale PID and failed with os error 232 at approximately 20:24Z, 21:04Z, and 00:23Z.

  8. At 00:31Z, a cross-session message found the target session absent from memory, resumed it from disk through a healthy CLI pool process, and completed successfully.

Expected behavior

When a liveness probe receives a definitive transport failure such as a closed stdio pipe:

  • Immediately invalidate the associated pooled CLI process, regardless of its current reference count.
  • Detach affected sessions from the failed pool entry.
  • Terminate/reap the failed process if it is still resident.
  • Spawn or select a healthy CLI process before retrying session.resume.
  • Never count multiple attempts against the same already-known-bad transport as independent retries.
  • Prevent future session creation for the working directory from selecting the invalid pool entry.

Actual behavior

  • The failure is detected correctly.
  • Automatic resume is attempted.
  • Every retry reuses the same broken process because existing_ref_count=2.
  • The session is marked interrupted after three guaranteed-to-fail retries.
  • Future sessions for the same working directory can inherit the same broken pool entry.
  • Recovery requires an external action that causes a healthy pool process to be selected or the app to be restarted.

Impact

  • Long-running sessions appear permanently stalled even though their durable state is recoverable.
  • The UI does not explain that retries repeatedly targeted a known-dead transport.
  • Users may start duplicate recovery sessions against the same working tree.
  • New sessions in the same project can fail until the stale pool entry is displaced.
  • The standalone CLI's service-call retry behavior does not help because this failure is in Desktop's child-process/stdio layer.

Related issues

Those issues cover adjacent failure modes, but I could not find one documenting the exact sequence where liveness detection succeeds, auto-resume runs, and all retries are knowingly routed back to the same failed pooled process because its reference count remains nonzero.

Diagnostic availability

The complete Desktop log and CLI session event log contain repository/session content and are not attached publicly. Sanitized excerpts, timestamps, and process/session correlation can be provided privately if maintainers need them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions