Skip to content

fix: gracefully handle stale ctx after session replacement#2

Open
RobGilto wants to merge 1 commit into
hsingjui:mainfrom
RobGilto:fix/stale-context-error
Open

fix: gracefully handle stale ctx after session replacement#2
RobGilto wants to merge 1 commit into
hsingjui:mainfrom
RobGilto:fix/stale-context-error

Conversation

@RobGilto

@RobGilto RobGilto commented Jun 6, 2026

Copy link
Copy Markdown

Problem

When running pi -p "prompt", the extension throws an error after the response is delivered:

Extension error (.../pi-hooks.ts): This extension ctx is stale after session replacement or reload.
Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(),
or ctx.reload().

The -p flag causes pi to create a session, run the prompt, then replace/reload the session. The extension's event handlers still hold a reference to the old ctx and try to use it after replacement.

Fix

Add a safeHandler wrapper in hook-context.ts that catches stale-context errors and returns silently. When a session is replaced mid-handler, the old session no longer exists — there is nothing useful the handler can do, so silently returning is the correct behavior.

All 9 pi.on() registrations across 5 hook modules are wrapped:

  • session-hooks.tssession_start, session_shutdown
  • prompt-hooks.tsinput, before_agent_start
  • compact-hooks.tssession_before_compact, session_compact
  • stop-hooks.tsagent_end
  • tool-hooks.tstool_call, tool_result

Testing

# Before fix: prints response + error
pi -p "hello world"
# => Hello! 👋 ...
# => Extension error (...): This extension ctx is stale...

# After fix: clean output
pi -p "hello world"
# => Hello! 👋 ...

When pi replaces a session mid-handler (e.g. Could you clarify what you'd like? For example:

- **"Show me the pi system prompt"** — I can display my current instructions
- **"Help me write a prompt"** — I can help craft a prompt for a specific task
- **"Explain pi prompt templates"** — I can read the relevant docs
- **Something else entirely?**

What are you looking for?), the
extension's captured ctx becomes stale and throws. This wraps all
pi.on() handlers with a safeHandler that catches stale-context errors
silently — the old session no longer exists, so there is nothing
useful to do.

The error was:
  Extension error: This extension ctx is stale after session
  replacement or reload. Do not use a captured pi or command ctx
  after ctx.newSession(), ctx.fork(), ctx.switchSession(), or
  ctx.reload().
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