Skip to content

IDE auto-connect falsely skipped as "already in use by another client" after forking/closing a session #4020

Description

@antonech

Describe the bug

After forking a session and later closing that fork, restarting/resuming the original session logs:

IDE auto-connect skipped: session is already in use by another client

and the CLI does not auto-connect to the IDE — even though no other client or session is actually running.

Root cause (from the shipped bundle, v1.0.68):

  • On create/resume, alreadyInUse = registerSessionLock(sessionId, dir), which returns aliveCount > 0 from an in-use lock sweep — i.e. whether any other live lock holder exists for that sessionId.
  • Lock liveness is tested with process.kill(pid, 0) only — host-local PID, with no hostname / boot-id / process-start-time recorded. The lock is keyed by sessionId and stores a per-PID file.
  • If the previous run of the session exited abruptly (crash, kill, or the fork-close workflow) it leaves a stale in-use lock file. On restart the recorded PID is either still alive or has been reused by an unrelated process, so the sweep counts it as alive → false alreadyInUse = true.
  • This is aggravated on shared/NFS state directories, where a PID from a different host passes the local kill(pid, 0) check.

Impact is low/cosmetic-functional: IDE auto-connect is suppressed for that session (no editor attach); it is logged ephemerally + a telemetry event. Core CLI behavior is otherwise unaffected.

Affected version

GitHub Copilot CLI 1.0.68

Steps to reproduce the behavior

  1. Start a session (S).
  2. Fork S into a separate session, open it, do some work, then close it.
  3. Restart / resume the original session S.
  4. Observe the log line IDE auto-connect skipped: session is already in use by another client, and that the IDE is not auto-connected — despite no other client running.

Expected behavior

When a session is restarted/resumed and no live client actually holds it, the CLI should detect the session as free and auto-connect to the IDE normally, as on a first launch.

Specifically:

  • A stale in-use lock left by a previously-exited (crashed, killed, or abruptly-closed) client — including one left by the fork workflow — must not be counted as a live holder.
  • Lock liveness must be immune to PID reuse, and a lock from a different host (shared/NFS state) must not be treated as locally "alive".
  • The session is already in use by another client message should appear only when a genuinely running, live client on the same host currently owns that session.

Additional context

Suggested fix: record {pid, hostname, boot-id or process start-time} in the in-use lock file and count it alive only when all match (skip locks from other hosts); and reliably release the in-use lock on session close / fork-close.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:sessionsSession management, resume, history, session picker, and session state

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions