Skip to content

fix(usage-status): prevent crash on Pi reload from stale ExtensionContext#51

Closed
rnavarro wants to merge 1 commit into
aliou:mainfrom
rnavarro:fix/stale-ctx-usage-status
Closed

fix(usage-status): prevent crash on Pi reload from stale ExtensionContext#51
rnavarro wants to merge 1 commit into
aliou:mainfrom
rnavarro:fix/stale-ctx-usage-status

Conversation

@rnavarro
Copy link
Copy Markdown

@rnavarro rnavarro commented May 5, 2026

Pi crashes on reload when the usage-status extension's setInterval timer fires with an ExtensionContext that has gone stale. The ExtensionContext.hasUI getter calls assertActive(), which throws after session replacement or reload.

I hit this when reloading Pi after switching providers with Ctrl+P. Pi would crash immediately with:

Error: This extension ctx is stale after session replacement or reload.
  at ExtensionRunner.assertActive (runner.js:297)

The timer callback and several other code paths accessed captured ctx properties (hasUI, ui.setStatus, modelRegistry) without checking liveness. A ctx that becomes stale during an async gap (e.g., after await getSyntheticApiKey) also caused unhandled rejections from the catch block re-touching ctx.ui.

Fix: Add isCtxLive() helper that safely probes hasUI in a try/catch to detect stale contexts, and apply it at every entry point that touches a captured ExtensionContext:

  • setInterval callback: isCtxLive guard before updateFooterStatus
  • stopAutoRefresh(): clear activeContext; guard ctx.ui access
  • updateFooterStatus(): isCtxLive at entry and after each await
  • updateFooterStatus() catch: guard against double-throw on stale ctx
  • updateFooterStatus() queuedRefresh: use activeContext instead of the captured ctx parameter (which may belong to a prior session)
  • setLoadingStatus(): isCtxLive after await
  • renderFromLastSnapshot(): isCtxLive guard
  • SYNTHETIC_CONFIG_UPDATED_EVENT handler: isCtxLive on currentContext

14 new tests cover the stale context guard, stop behavior, mid-session staleness, stopAutoRefresh with stale ctx, and non-UI mode (hasUI=false on a live context).

…text

Pi crashes on reload when the usage-status extension's setInterval
timer fires with an ExtensionContext that has gone stale. The
ExtensionContext.hasUI getter calls assertActive(), which throws
after session replacement or reload.

I hit this when reloading Pi after switching providers with Ctrl+P.
Pi would crash immediately with:

  Error: This extension ctx is stale after session replacement
  or reload.
    at ExtensionRunner.assertActive (runner.js:297)

The timer callback and several other code paths accessed captured
ctx properties (hasUI, ui.setStatus, modelRegistry) without
checking liveness. A ctx that becomes stale during an async gap
(e.g., after await getSyntheticApiKey) also caused unhandled
rejections from the catch block re-touching ctx.ui.

Add isCtxLive() helper that safely probes hasUI in a try/catch
to detect stale contexts, and apply it at every entry point that
touches a captured ExtensionContext:

- setInterval callback: isCtxLive guard before updateFooterStatus
- stopAutoRefresh(): clear activeContext; guard ctx.ui access
- updateFooterStatus(): isCtxLive at entry and after each await
- updateFooterStatus() catch: guard against double-throw
- updateFooterStatus() queuedRefresh: use activeContext instead
  of the captured ctx parameter (which may belong to a prior session)
- setLoadingStatus(): isCtxLive after await
- renderFromLastSnapshot(): isCtxLive guard
- SYNTHETIC_CONFIG_UPDATED_EVENT handler: isCtxLive on currentContext

14 new tests cover the stale context guard, stop behavior,
mid-session staleness, stopAutoRefresh with stale ctx, and
non-UI mode (hasUI=false on a live context).
@aliou
Copy link
Copy Markdown
Owner

aliou commented May 5, 2026

Hey @rnavarro, thank you for the PR! But instead of keeping using a potentially stale extension context, the data will no longer be polled, but live updated by calls to the provider. This is handled in #44 and #52 , that are going to be merged in the release tomorrow morning.

@aliou aliou closed this May 5, 2026
@rnavarro
Copy link
Copy Markdown
Author

rnavarro commented May 5, 2026

Nice! Good stuff, thanks for all you do on this extension!

@rnavarro rnavarro deleted the fix/stale-ctx-usage-status branch May 5, 2026 21:12
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.

2 participants