fix: await session_start to prevent stale ctx access - #16
Merged
Conversation
Fire-and-forget onSession() could resolve after a session was replaced, then read ctx.cwd / call ctx.ui.notify on the now-stale ctx and trigger ExtensionRunner.assertActive throw. Await the handler so the runner serializes init before any replacement; log via console.error in the catch so the error path doesn't access ctx either. Surfaces on @earendil-works/pi-coding-agent >=0.74. Tested at 0.79.6.
tintinweb
added a commit
that referenced
this pull request
Jun 23, 2026
session_start is now awaited (#16), so a hung `gitnexus --version` would stall pi boot. trySpawn had no timeout (unlike resolveShellPath). Add a default 5s ceiling so a slow/broken gitnexus-cmd can't block init.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
pi-gitnexus@0.6.3crashes during boot when used with@earendil-works/pi-coding-agent >=0.74if a session replacement happens during init (resume, fork, switch, reload). Hit this onpi-coding-agent@0.79.6.Root cause
src/index.ts:273-277registers thesession_starthandler as fire-and-forget:onSession(ctx)does several awaits:resolveShellPath(),probeGitNexusBinary()(spawn),findGitNexusIndex(ctx.cwd). The synchronous handler returns immediately after kicking off the promise. The agent loop sees session_start as done, may run a session replacement next turn (or even concurrently during boot, depending on launcher), and thenonSession's async tail readsctx.cwd/ callsctx.ui.notifyon a now-stale ctx. Upstream'sExtensionRunner.assertActivethrows on any access.Fix
Make the handler
asyncandawait onSession. The runner serially awaits eachsession_starthandler, so init completes before the loop continues and ctx replacement can happen.Also switched the catch from
ctx.ui.notifytoconsole.errorso the error path doesn't trip the same staleness check if the throw happens after handler resumption.Diff
Repro
Launch pi with pi-gitnexus enabled, then fork/switch/reload a session before GitNexus init completes (
onSessionis awaitingresolveShellPath()andprobeGitNexusBinary()). On>=0.74the next ctx access in the deferred chain throws viaassertActive.In my case it surfaced on cold-start of a fresh pi-ult-code launch with ~30 other extensions also firing session_start in parallel, which pushed the agent loop's session replacement window past gitnexus's spawn time.
Notes
probeGitNexusBinary()will delay pi boot. In practice the probe is fast (singlegitnexus --versionspawn), buttrySpawnatsrc/index.ts:80has no timeout. If anyone hits a hanging customgitnexus-cmd, boot blocks until the upstream runner watchdog skips it (or indefinitely on older runners without that watchdog). Filing this as a follow-up rather than scope-creeping this PR; happy to add the timeout here if you want.git diff --checkclean. Verified at runtime against@earendil-works/pi-coding-agent@0.79.6via a pi-ult-code launch with the full extension set loaded; pre-fix the launch crashed on the trace above, post-fix it boots clean and/gitnexus statusworks.