From 4ff9c8d3008995d47c50d73f7fefdfa588e22c3e Mon Sep 17 00:00:00 2001 From: mayor Date: Tue, 13 Jan 2026 18:13:10 +0100 Subject: [PATCH] fix(tui): track all timeouts in Footer to prevent memory leak The Footer component's tick() function creates recursive timeouts but only stores the most recent timeout ID. When the component unmounts, only the last timeout is cleared - earlier ones continue running. Track all timeout IDs in an array and clear them all in onCleanup() to ensure proper cleanup on unmount. --- .../src/cli/cmd/tui/routes/session/footer.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/footer.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/footer.tsx index d10c49c833f..8ace2fff372 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/footer.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/footer.tsx @@ -25,24 +25,27 @@ export function Footer() { }) onMount(() => { + // Track all timeouts to ensure proper cleanup + const timeouts: ReturnType[] = [] + function tick() { if (connected()) return if (!store.welcome) { setStore("welcome", true) - timeout = setTimeout(() => tick(), 5000) + timeouts.push(setTimeout(() => tick(), 5000)) return } if (store.welcome) { setStore("welcome", false) - timeout = setTimeout(() => tick(), 10_000) + timeouts.push(setTimeout(() => tick(), 10_000)) return } } - let timeout = setTimeout(() => tick(), 10_000) + timeouts.push(setTimeout(() => tick(), 10_000)) onCleanup(() => { - clearTimeout(timeout) + timeouts.forEach(clearTimeout) }) })