Repository navigation
fix(server): detach errored provider sessions when deleting threads - #34199
romil-bijarnia wants to merge 1 commit into
Conversation
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Deleting a thread now detaches errored provider sessions too, preventing live runtimes and credentials from lingering. The change reuses existing thread-scoped cleanup and shared-session safeguards. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
binjamshid
left a comment
There was a problem hiding this comment.
The fix matches the stated failure: ProviderSessionManager.detach is already a no-op when the entry is gone or the thread is not attached, and it still runs clearMcpSession when revokeMcpCredential is set, so emitting the detach for an error session is safe even when that runtime is actually dead. The projection drops the session on provider-session.detached, and the extended planner case pins both the effect and the projection result.
- (low, follow-up, outside this diff) The same
status !== "stopped" && status !== "error"filter also gates detaches on the provider-switch / fresh-context / worktree-change paths inapps/server/src/orchestration-v2/Orchestrator.ts(around lines 2130, 4576 and 6827 on current main). If an errored session can still own a reusable live runtime, those paths leave the thread attached in the same way. Keeping it out of this PR is reasonable; it may be worth a separate issue so the rule stays consistent.
The comment at ThreadDeletion.ts:186 explains the rule well. No other concerns.
|
Note Written by Verified in a real dev environmentRan To get a live session in On web, deleting a single thread from the sidebar does not reproduce the bug on After Remove project on a project holding the errored Pi thread:
main transcriptPR transcriptRemove project on Remove project on this PR (process exits and credential is revoked, see transcript): Neighbor checks on the PR build, all passing:
CI on Not verified
|
Problem
Deleting a thread skips provider sessions whose persisted status is
error. An errored session can still own a reusable live runtime:ProviderSessionManagerdeliberately retains those sessions. The delete therefore omits the per-thread detach effect and its MCP-credential revocation, leaving a deleted thread attached to the runtime with a valid credential.Change
Skip only sessions that are already stopped. Errored sessions now use the same existing detach event and effect as other live sessions. Extend the existing deletion-planner case to require detaching both running and errored sessions, retain the stopped-session exclusion, and keep the earlier deletion timestamp.
The existing session manager still handles shared runtimes, per-thread unloading, credential revocation and idle release. This does not force-close the shared provider process or change session lifetime policy.
Scope and approval
A small, focused fix for an obvious omission in the existing delete lifecycle, submitted under the bug-fix exception. Two files, one underlying problem, no new settings, provider-specific behavior, contracts or UI.
Searched current open PRs for thread deletion and errored-session cleanup. #34175 concerns device claims during archive/delete, not provider-session detachment; #31658 concerns recovery of rejected Codex conversations.
Verification
Linux arm64, Node 26.12.1, base
42185a6206245c1cde5368e8ce368b384e7a400a.Red first: the extended deletion-planner case retains
["stopped", "error"]instead of["stopped"]and omits the error session's detach effect on unchanged production code.With the fix, 5 focused cases pass across
ThreadDeletion.test.tsandProviderSessionManager.test.ts: deletion/resource planning, active-work disposal, reusable error states, terminal credential revocation, and independent detach on shared runtimes.A standalone runtime exercise reused the existing fake-provider fixture with the production session manager, in-memory SQLite projection/event stores, real MCP registry, and deletion planner. It emitted a reusable session error, awaited that exact event, committed the deletion events, and executed the planned detach through the production manager:
No real provider turn, account, live database, or desktop UI was used. The exercise invokes the planned detach directly, rather than through the asynchronous effect worker. Existing worker routing is unchanged.
vp run check:changed 42185a6206245c1cde5368e8ce368b384e7a400a --concurrency 2passes format, lint, both knip checks, GraphQL, typechecks for 3 affected packages, and all 4 selected tests across 2 files.