Skip to content

fix(core): close promise plugin event subscriptions on scope teardown - #38825

Closed
tiffanychum wants to merge 849 commits into
anomalyco:devfrom
tiffanychum:fix/36677-plugin-event-leak
Closed

tiffanychum wants to merge 849 commits into
anomalyco:devfrom
tiffanychum:fix/36677-plugin-event-leak

Conversation

@tiffanychum

@tiffanychum tiffanychum commented Jul 25, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #36677

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Promise-based plugins that detach a for await on ctx.event.subscribe() never called return(), so each location expiry/reboot leaked a process-global PubSub subscriber and fan-out grew until idle servers burned a core on allocation. The promise bridge now registers a plugin-scope finalizer that closes the async iterator, so generation teardown unsubscribes even when the plugin never returns the iterator.

How did you verify your code works?

bun test test/plugin/promise.test.ts (10/10) and bun typecheck in packages/core.

Screenshots / recordings

N/A — not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

rekram1-node and others added 30 commits July 17, 2026 00:15
Keep draining standalone server stdout after reading its readiness message so
later server output does not write into a closed pipe.

Install the Node CLI broken-pipe handler before loading the main entrypoint.
Ignore only EPIPE while preserving all unrelated stdout errors. This prevents
Windows Node builds from failing when the TUI prints its exit epilogue after
renderer teardown.
Co-authored-by: Aiden Cline <[email protected]>
Co-authored-by: Aiden Cline <[email protected]>
@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. needs:issue labels Jul 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@tiffanychum
tiffanychum changed the base branch from v2 to dev July 25, 2026 09:34
@github-actions github-actions Bot removed needs:issue needs:compliance This means the issue will auto-close after 2 hours. labels Jul 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@tiffanychum

Copy link
Copy Markdown
Author

Closing without merging: this branch was rebuilt/re-checked against current dev, and the original leak path is no longer reachable.

What changed upstream

  • PR fix(core): close promise plugin event subscriptions on scope teardown #38825 patched ctx.event.subscribe() in the Promise-plugin bridge (packages/core/src/plugin/promise.ts), closing the async iterator on plugin-scope teardown.
  • That API was removed when the namespaced hook API landed (909a1a6d7, “feat(plugin): add namespaced hook API”). Current PluginContext (Promise and Effect) has no event field; PluginHost.make does not expose one. packages/plugin/src/v2/effect/event.ts is an orphaned type stub and is not wired into the host.
  • Cherry-picking the old fix onto current dev still conflicts for that reason.

What we checked on current dev

  • No Promise/Effect plugin path can call ctx.event.subscribe() / Stream.toAsyncIterable(host.event.subscribe()).
  • Built-in subscribers that still use EventV2 (models-dev, opencode provider) run via Effect.forkScoped, so they are tied to the plugin/location scope rather than an unmanaged async iterator.
  • Without a reachable repro of subscriber accumulation across location invalidate/expiry, inventing a replacement fix would be speculative.

Leaving #36677 open for maintainer re-triage in case the original allocation-loop report still has a different root cause.

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.

core: long-lived V2 server enters persistent allocation loop

8 participants