Skip to content

Watcher wedges on every arm; supervision stays down; only a session restart recovers #2251

Description

@mayankasthana

Symptom

The firstmate watcher process starts and then wedges silently within minutes: it never touches its liveness beacon, never writes to the triage log, and holds the watch lock while idle. Every re-arm produces another wedged watcher. Wake delivery via the Pi extension still works, but the watcher itself is dead, the turn-end guard blocks turns, and the only recovery is restarting the Pi session.

Environment (reported by operator, 2026-08-12)

  • Firstmate version: b5d430d (updated 2026-08-12; includes feat(fmx-respond): consume Relay conversation chains (#2206) and fix(bin): prevent watcher recovery acknowledgement livelock (#2212))
  • Harness / agent: pi (Pi coding agent CLI) v0.84.1
  • Model: deepseek-v4-flash (deepseek provider) — used by the primary and all crewmates
  • Runtime backend: herdr (HERDR_ENV=1, experimental session-provider backend; many concurrent herdr panes at wedge time)
  • OS: macOS 26.4.1 (Build 25E253)
  • Node: v25.9.0 · npm 11.12.1
  • Timezone: IST

Reproduction context (observed 2026-08-12, macOS, pi primary, herdr backend)

  • Watcher ran normally until ~12:43 IST (triage log active, beats fresh).
  • From 12:43 onward: 6+ consecutive arms each wedged within minutes (process alive, S+ state, no beat, no triage-log output after start).
  • fm_watch_arm_pi returns "unchanged - extension already owns an arm child" even after all arm/watcher processes were killed; the extension keeps spawning new arms that wedge again.
  • Process sample shows bash stuck deep in a wait (child/syscall wait, not resolvable in the sample head).
  • Full home-scoped cleanup (kill wedged watcher+arm PIDs, remove stale .watch.lock + owner dir, remove stale .watcher-down lock owner/steal dirs) did NOT help — the next fresh arm wedged the same way.
  • Earlier in the day, a wake-drain lock acquisition was observed dying with SIGKILL ("Killed: 9") during ln -s lock creation — possible related resource/state pressure.
  • No state/*.check.sh files were present at wedge time (all checks quarantined), so the hang is not a check execution.

Suspected areas

  • bin/fm-watch.sh poll loop / lock acquisition deadlock (possibly a stale lock-owner dir or a subprocess it waits on that hangs).
  • .pi/extensions/fm-primary-pi-watch.ts arm verification: the arm child "did not exit within 1000ms" and the extension can never verify a ready successor, so it keeps an unwedged-looking arm claim that blocks manual re-arm.
  • .watcher-down recovery/lock state interplay with the ack-livelock area recently fixed in fix(bin): prevent watcher recovery acknowledgement livelock #2212.

Impact

Supervision down for hours with live fleet work; turn-end guard blocks; the documented repair (session restart) is disruptive. The watcher should fail loudly and recover, or at least release the lock so a manual re-arm can take over.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-prTriage: real bug or VISION-aligned feature, open for a PR

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions