github / github/copilot-cli

Sessions become unrevivable: a stale `inuse.<pid>.lock` from a crashed host is never reclaimed on open

Aperta
#4,805 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

triage
Lingua principale
Shell
Stelle
11.2k
Fork
1.9k
Merge medio
14h 16m
PR unite (30g)
6

Descrizione

Describe the bug

Several saved sessions became impossible to reopen ("crashed out / unrevivable"). On investigation the session data was not corrupt — the append-only events.jsonl replayed cleanly and the engine logged a successful resume. The sessions were blocked by runtime/lifecycle issues, not data loss.

The primary cause is stale lock handling. Each live session writes ~/.copilot/session-state/<id>/inuse.<pid>.lock. When the owning copilot --server process exits uncleanly (crash, force-quit, OS kill), the lock file is left behind. On the next open, the session is treated as in-use / unrevivable instead of checking whether that PID is still alive.

Scanning one local store, 14 of 184 sessions (~8%) carried a fault signature; 8 held an inuse.<pid>.lock whose PID was dead. Deleting the stale lock made each session openable again, and the app then spawned a fresh host and resumed normally — confirming the data was fine and only the lock blocked recovery.

Three related lifecycle defects compound the impact (details under Additional context):

  1. Orphaned engine host after a failed UI attach — the engine resumes but no session host registers, leaving a live server holding the lock (which then becomes defect #1 on the next attempt).
  2. MCP OAuth timeouts block session readiness — resume stalls ~5 minutes on OAuth callback timeout before the session is interactive, so users abort.
  3. Unbounded events.jsonl makes replay hang on large/old sessions (appears to overlap #4251).
Affected version

1.0.83 (copilot --server --stdio --no-auto-update)

Steps to reproduce the behavior

Primary defect (stale lock not reclaimed):

  1. Open a session, then hard-kill its copilot --server process to simulate a crash / force-quit (kill -9 <pid>).
  2. Confirm ~/.copilot/session-state/<id>/inuse.<pid>.lock remains, now pointing at a dead PID.
  3. Try to reopen the session → it does not revive.
  4. rm the stale lock file → the session reopens and resumes cleanly (a fresh host is spawned and events.jsonl replays without error).
Expected behavior

On open, if the lock's PID is dead or a zombie, the app should reclaim the session automatically rather than treating it as in-use. A liveness check combined with a PID start-time comparison avoids the classic PID-reuse race. Recoverable work should never be gated behind a leftover lock file that only manual filesystem surgery can clear.

Additional context
  • OS: macOS · shell: zsh

Defect 2 — orphaned engine host after a failed UI attach. Engine log from a single resume: the host never registers, yet the engine reports the session resumed, so the process lingers as an orphan holding the lock:

[WARNING] [rust:copilot_runtime::session::pending_request_flow] pending-request event was not delivered to the session host
          {"error":"GenericFailure, no session host is registered for session <id>"}
...
[INFO]  Resumed session: <id>        (logged repeatedly)

Suggested fix: tie the engine host's lifetime to successful UI host registration; if registration fails/times out, tear the host down and release the lock.

Defect 3 — MCP OAuth timeouts block resume (~5 min). With several MCP servers configured, resume stalls until interactive OAuth flows time out. MCP init begins at 20:27, first hard failures at 20:32:

[ERROR] [rust:mcp_engine::session_authorizer] OAuth login failed after returning its authorization URL
        {"server_name":"...","error":"OAuth callback timeout"}

During that window the session looks hung and users abort — observed as sessions whose only recent events were resume → abort (user_initiated) → shutdown, twice in a row. Suggested fix: make MCP init lazy / non-blocking; never gate session interactivity on MCP OAuth.

Defect 4 — unbounded events.jsonl. The append-only log grows without bound; worst local session reached 38.6 MB / ~13k events with 42 compaction cycles (173 re-injected system.message events ≈ 10.7 MB). Reopening replays the whole log, so large sessions hang on open even though nothing is corrupt. This looks like the same root cause as #4251; noting here for linkage. Suggested fix: snapshot-and-truncate the event log at compaction so replay cost stays bounded.

Possibly related: #4020 (session falsely "already in use by another client"), #4098 (truncated/concatenated events on resume), #4138 (resume compaction hangs), #4251 (large-session resume OOM/hang).

All four are addressable without changing the on-disk event format. Defects 1–2 turn recoverable work into apparent data loss; 3–4 make large/older sessions feel dead on open.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia tracciando la gestione di session-open per ~/.copilot/session-state//inuse..lock e il ciclo di vita di copilot --server. Riproduci il caso di una terminazione forzata, quindi esamina il runtime della sessione Rust per quanto riguarda il recupero dei lock e la registrazione dell’host; il difetto principale è risolto quando un PID terminato o zombie non blocca più la riapertura e la sessione riprende senza rimuovere manualmente il lock. Le problematiche relative a OAuth e events.jsonl devono essere trattate come ambito separato.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
rust
Ambito
backend, cli
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Attiva
Chiarezza
Abbastanza chiara
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.