fix(pi): avoid stale ctx.ui after async health check#1036
Conversation
refreshStatus awaited getHealth() then accessed ctx.ui.setStatus. If the pi session was replaced or reloaded during that await, the extension context is invalidated and assertActive throws: This extension ctx is stale after session replacement or reload Capture setStatus while ctx is still active, and treat post-await status updates as best-effort. AI-Agent: Pi AI-Session-IDs: current
|
@yulin0629 is attempting to deploy a commit to the rohitg00's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough
ChangesPi Status Refresh Fix
Estimated code review effort: 1 (Trivial) | ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Fixes a race in the integrations/pi extension where refreshStatus() could throw by accessing ctx.ui after awaiting an async health check, making the status update best-effort when the pi session is replaced/reloaded mid-await.
Changes:
- Capture
ctx.ui.setStatusbefore awaitinggetHealth()to avoid stale-context access after the await. - Wrap the post-await status-line update in
try/catchso session replacement doesn’t surface as an extension error.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let setStatus: ((key: string, text: string) => void) | undefined; | ||
| try { | ||
| setStatus = ctx.ui.setStatus.bind(ctx.ui); | ||
| } catch { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Good catch — updated to capture const ui = ctx.ui once and bind from that single reference, so we no longer read the session-bound getter twice. Pushed in the follow-up commit.
Address review feedback: avoid reading ctx.ui twice when capturing the status setter. Bind from a single local ui reference. AI-Agent: Pi AI-Session-IDs: current
Summary
Fixes a race in the official pi extension where
refreshStatus()awaitsgetHealth()and then accessesctx.ui.setStatus. If the pi session is replaced/reloaded during that await, pi invalidates the extension context andassertActive()throws:This extension ctx is stale after session replacement or reloadThis surfaces as a noisy extension error and can skip memory-recall injection for that turn.
Fixes #1035
Change
In
integrations/pi/index.tsrefreshStatus:ctx.ui.setStatusbefore the await (while ctx is still active).No behavior change for the healthy path; only avoids throwing when the session is already gone.
Test plan
mainintegrations/pi/index.ts/reload, stale-ctx error no longer reproduces on normal prompts/reload//newduring await — should not throw stale ctx🧠 agentmemoryNotes
agentmemory connect picurrently documents manual copy of these files; published npm package does not shipintegrations/infiles.Summary by CodeRabbit