[PR #9147] fix(memory): Fix event listener leaks in TUI and Slack bot #13004

Open
opened 2026-02-16 18:17:53 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/9147

State: open
Merged: No


Summary

Fix memory leaks from event listeners not being properly cleaned up in TUI components and the Slack bot.

Fixes #9155

Problems

1. TUI Sync Context (sync.tsx)

The sdk.event.listen() call sets up event listeners but the returned unsubscribe function is never called.

2. Tooltip Component (tooltip.tsx)

Mouse event listeners are added to elements but never removed on component unmount.

3. Slack Bot (slack/index.ts)

  • Sessions Map grows without bounds
  • No cleanup of old/stale sessions
  • No graceful shutdown handling

Solution

TUI Sync Context

Store and call unsubscribe function in onCleanup:

const unsubscribe = sdk.event.listen((e) => { ... })
onCleanup(unsubscribe)

Tooltip Component

Add proper cleanup in onCleanup handler.

Slack Bot

  • Add lastUsed timestamp to sessions
  • Add periodic cleanup of sessions older than 1 hour
  • Add MAX_SESSIONS limit (100)
  • Add graceful shutdown handlers for SIGINT/SIGTERM

Changes

  • packages/opencode/src/cli/cmd/tui/context/sync.tsx - Store and call unsubscribe
  • packages/ui/src/components/tooltip.tsx - Add event listener cleanup
  • packages/slack/src/index.ts - Add session management and shutdown handlers

Testing

  • TypeScript compilation passes (bun turbo typecheck)
  • Unit tests pass (725 tests, 0 failures)

Note: Manual TUI and Slack bot testing was not performed. Memory leak verification requires runtime memory profiling.

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/9147 **State:** open **Merged:** No --- ## Summary Fix memory leaks from event listeners not being properly cleaned up in TUI components and the Slack bot. Fixes #9155 ## Problems ### 1. TUI Sync Context (`sync.tsx`) The `sdk.event.listen()` call sets up event listeners but the returned unsubscribe function is never called. ### 2. Tooltip Component (`tooltip.tsx`) Mouse event listeners are added to elements but never removed on component unmount. ### 3. Slack Bot (`slack/index.ts`) - Sessions Map grows without bounds - No cleanup of old/stale sessions - No graceful shutdown handling ## Solution ### TUI Sync Context Store and call unsubscribe function in `onCleanup`: ```typescript const unsubscribe = sdk.event.listen((e) => { ... }) onCleanup(unsubscribe) ``` ### Tooltip Component Add proper cleanup in `onCleanup` handler. ### Slack Bot - Add `lastUsed` timestamp to sessions - Add periodic cleanup of sessions older than 1 hour - Add `MAX_SESSIONS` limit (100) - Add graceful shutdown handlers for SIGINT/SIGTERM ## Changes - `packages/opencode/src/cli/cmd/tui/context/sync.tsx` - Store and call unsubscribe - `packages/ui/src/components/tooltip.tsx` - Add event listener cleanup - `packages/slack/src/index.ts` - Add session management and shutdown handlers ## Testing - [x] TypeScript compilation passes (`bun turbo typecheck`) - [x] Unit tests pass (725 tests, 0 failures) **Note:** Manual TUI and Slack bot testing was not performed. Memory leak verification requires runtime memory profiling.
yindo added the pull-request label 2026-02-16 18:17:53 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#13004