Skip to content

fix: self-heal sessions evicted from the backend (Session is not active -32004) - #69

Merged
william0wang merged 1 commit into
mainfrom
fix/session-eviction-recovery
Aug 22, 2026
Merged

fix: self-heal sessions evicted from the backend (Session is not active -32004)#69
william0wang merged 1 commit into
mainfrom
fix/session-eviction-recovery

Conversation

@william0wang

Copy link
Copy Markdown
Owner

Problem

Replying to a conversation in the editor sometimes failed with:

session/subscribe failed: Session is not active: sess_… (code -32004)

while remote clients saw the same session as empty (the editor still
showed its local copy of the history).

Root cause (verified against live backend)

The zcode backend evicts idle resident runtimes after ~10 minutes
(observed log: session.resident_deactivated, reason: "idle_timeout",
idleTimeoutMs: 600000) and also keeps an LRU cap on residents. An evicted
session fails every session-scoped RPC with -32004 while the session
file stays intact:

method evicted session after session/resume
session/read ERROR -32004 (fast fail) OK
session/messages ERROR -32004 → fetchMessages swallows → empty replay (the "remote sees empty session" symptom) OK
session/subscribe ERROR -32004 (the editor error) OK
session/resume reloads the session fully

The bridge trusted in-memory state forever: sessionMap returned the stale
sid from prompt(), and a stale backendLoadedSessions flag made
session/load skip the backend resume RPC.

Fix — self-healing on every entry point

  • prompt(): on Session is not active from subscribe → session/resume
    reload → re-baseline the differ (so turn completion doesn't diff-replay the
    whole history) → retry the subscribe once. Other errors propagate unchanged.
  • TTL on the loaded-verification (BACKEND_RESIDENT_TTL_MS = 5min, half
    the eviction window): session/load·resume stop trusting stale
    verifications and re-issue the resume RPC; timestamps refresh on subscribe
    success and turn completion.
  • ensureRealSession(): config/slash/extension entry points reload a
    stale mapping before use — skipped while a turn is in flight (a running
    turn proves the resident is live), fail-safe on reload failure.

Testing

  • New tests/session-eviction.test.ts (8 cases): prompt recovery + re-baseline,
    non-eviction error propagation, recovery-resume failure propagation, TTL
    expiry, stale-mapping reload, in-flight skip, fail-safe.
  • Full suite: 678/678 passed; typecheck/lint/build clean.
  • docs/TROUBLESHOOTING.md: dedicated -32004 entry (also corrected the
    subscribe timeout retry numbers).
  • Version 0.11.3 + CHANGELOG.

@william0wang
william0wang merged commit a801996 into main Aug 22, 2026
1 check passed
@william0wang
william0wang deleted the fix/session-eviction-recovery branch August 22, 2026 01:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant