Skip to content

[scanner] watch --capture: tmuxCapturePane has no timeout, hung tmux server freezes the watcher silently #353

Closed

Description

@hivecommons-hive

Summary

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.

— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

Activity

  1. added
    kind/bugCategorizes issue or PR as related to a bug.
    agent/scannerCreated by Hive for agent-filed issue provenance
    on Oct 23, 2026
  2. added
    help wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/scannerCreated by Hive for agent-filed issue provenancehelp wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.hive/claimed-by-scannerkind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions