You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[scanner] watch --capture: tmuxCapturePane has no timeout, hung tmux server freezes the watcher silently #353
pluk watch --capture polls tmux capture-pane -p synchronously (execFileSync) once per interval, but tmuxCapturePane passes no timeout. If the tmux server hangs (wedged server, stalled control socket, suspended tmux under heavy I/O), the call blocks the Node event loop indefinitely: the catch in the poll loop that increments captureFailures never runs, the --diagnostics timer cannot fire (the loop is blocked), and the watcher appears alive while emitting nothing — the exact silent-stall failure mode --diagnostics exists to expose.
src/tmux.ts itself documents this as the reason the seam exists:
only the list-sessions call site set a timeout, so a hung tmux server could block the others indefinitely. Routing every call through here keeps the per-command options in one place
…but only tmuxListSessionNames (timeout: 5000) actually sets one. tmuxCapturePane — the only call that runs unattended in a long-lived process on a timer — is the one that most needs it.
Where
src/tmux.ts — tmuxCapturePane(target): execFileSync('tmux', ['capture-pane', '-p', '-t', target], { encoding: 'utf-8', stdio: [...] }) with no timeout.
src/watch.ts capture branch: setInterval(() => { ... tmuxCapturePane(target) ... } catch { stats.captureFailures++ } }, intervalMs) — relies on the call returning or throwing.
Expected
A bounded timeout on tmuxCapturePane (e.g. the same 5000 ms used by list-sessions, or min(5000, intervalMs) so a slow poll never overlaps the next tick) so a hung tmux server surfaces as a thrown ETIMEDOUT → captureFailures++ → visible in --diagnostics, instead of a permanently frozen watcher. A unit test that stubs the capture call to hang/throw and asserts captureFailures increments would pin the contract.
Decision taken by hive
Apply the timeout at the tmux.ts seam (single place, matching the file's stated intent) rather than per call site; keep the one-shot interactive commands (attach, new-session, send-keys, pipe-pane) unchanged since the user can interrupt those.
Activity