[PR #9148] fix(memory): Fix timeout, interval, and subscription cleanup #13007

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

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

State: open
Merged: No


Summary

Fix various small memory leaks from uncleaned timeouts, intervals, and event subscriptions across the codebase.

Fixes #9156

Problems

1. WebFetch Timeout (webfetch.ts)

When fetch throws an error, the timeout is not cleared.

2. Models setInterval (models.ts)

A setInterval is created but never cleared, even when the module is unloaded.

3. Bus.subscribe Return Value (github.ts)

The unsubscribe function returned by Bus.subscribe() is not captured or called.

Solution

WebFetch - Use try/finally

const timeout = setTimeout(...)
try {
  const response = await fetch(...)
  return response
} finally {
  clearTimeout(timeout)
}

Models - Track interval for cleanup

const intervalId = setInterval(...)
process.on("exit", () => clearInterval(intervalId))

Bus.subscribe - Capture unsubscribe

Store the unsubscribe function for later cleanup.

Changes

  • packages/opencode/src/util/webfetch.ts - Clear timeout in finally block
  • packages/opencode/src/provider/models.ts - Add interval cleanup on exit
  • packages/opencode/src/github/github.ts - Capture Bus.subscribe return value

Testing

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

Note: Manual testing of timeout/interval cleanup requires runtime verification which was not performed.

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/9148 **State:** open **Merged:** No --- ## Summary Fix various small memory leaks from uncleaned timeouts, intervals, and event subscriptions across the codebase. Fixes #9156 ## Problems ### 1. WebFetch Timeout (`webfetch.ts`) When fetch throws an error, the timeout is not cleared. ### 2. Models setInterval (`models.ts`) A setInterval is created but never cleared, even when the module is unloaded. ### 3. Bus.subscribe Return Value (`github.ts`) The unsubscribe function returned by `Bus.subscribe()` is not captured or called. ## Solution ### WebFetch - Use try/finally ```typescript const timeout = setTimeout(...) try { const response = await fetch(...) return response } finally { clearTimeout(timeout) } ``` ### Models - Track interval for cleanup ```typescript const intervalId = setInterval(...) process.on("exit", () => clearInterval(intervalId)) ``` ### Bus.subscribe - Capture unsubscribe Store the unsubscribe function for later cleanup. ## Changes - `packages/opencode/src/util/webfetch.ts` - Clear timeout in finally block - `packages/opencode/src/provider/models.ts` - Add interval cleanup on exit - `packages/opencode/src/github/github.ts` - Capture Bus.subscribe return value ## Testing - [x] TypeScript compilation passes (`bun turbo typecheck`) - [x] Unit tests pass (725 tests, 0 failures) **Note:** Manual testing of timeout/interval cleanup requires runtime verification which was not performed.
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#13007