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
- Start a session (S).
- Fork S into a separate session, open it, do some work, then close it.
- Restart / resume the original session S.
- 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.
Describe the bug
After forking a session and later closing that fork, restarting/resuming the original session logs:
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):
alreadyInUse = registerSessionLock(sessionId, dir), which returnsaliveCount > 0from an in-use lock sweep — i.e. whether any other live lock holder exists for thatsessionId.process.kill(pid, 0)only — host-local PID, with no hostname / boot-id / process-start-time recorded. The lock is keyed bysessionIdand stores a per-PID file.alreadyInUse = true.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
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:
session is already in use by another clientmessage 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.