Timers 1.7.1: a failed LTC capture spawn retries instead of parking #45

Open
michael wants to merge 1 commits from claude/timers-ltc-spawn-error into main
Owner

The bug (AB, 2026-10-04)

When spawn() itself fails — EACCES on a helper that lost its execute bit, as the 1.10.2 catalog install did (shell fix in PR #44), or ENOENT — the child emits 'error' with no 'exit' to follow. ltc-listener.js's error handler reported the error but left child set and scheduled nothing:

  • the 250 ms eval loop (if (stopped || !child) return) saw a truthy child and kept reporting a misleading "No signal" over the dead child object, immediately burying the one error report;
  • no restart was ever scheduled, so the listener was parked until a remount.

That is exactly what AB showed: EACCES spawn, tile said "No signal", no error anywhere, no capture process running — and Timers needed a remount after the chmod +x, while SPL healed itself (its spl-listener.js error path already nulls the child and retries).

The fix

Mirror spl-listener.js: in the 'error' handler, keep the error report, null child, and scheduleRestart(BAD_CONFIG_RETRY_MS). With child null the eval loop stops reporting, so the error stays visible on the tile, and the 30 s retry picks the helper up as soon as it is runnable again.

Module version 1.7.0 → 1.7.1.

Testing

  • ltc.selftest.js (all checks) and phase.selftest.js (66 checks) pass.
  • Scratch repro of the AB scenario (helper present but mode 0644): old code's last report is {state:"nosignal"} over a dead child; fixed code reports Capture tool unavailable — see Admin / LTC capture failed to start: spawn … EACCES once and nothing overwrites it.

🤖 Generated with Claude Code

## The bug (AB, 2026-10-04) When `spawn()` itself fails — EACCES on a helper that lost its execute bit, as the 1.10.2 catalog install did (shell fix in PR #44), or ENOENT — the child emits `'error'` with no `'exit'` to follow. `ltc-listener.js`'s error handler reported the error but left `child` set and scheduled nothing: - the 250 ms eval loop (`if (stopped || !child) return`) saw a truthy `child` and kept reporting a misleading **"No signal"** over the dead child object, immediately burying the one error report; - no restart was ever scheduled, so the listener was parked until a remount. That is exactly what AB showed: EACCES spawn, tile said "No signal", no error anywhere, no capture process running — and Timers needed a remount after the `chmod +x`, while SPL healed itself (its `spl-listener.js` error path already nulls the child and retries). ## The fix Mirror `spl-listener.js`: in the `'error'` handler, keep the error report, null `child`, and `scheduleRestart(BAD_CONFIG_RETRY_MS)`. With `child` null the eval loop stops reporting, so the error stays visible on the tile, and the 30 s retry picks the helper up as soon as it is runnable again. Module version 1.7.0 → **1.7.1**. ## Testing - `ltc.selftest.js` (all checks) and `phase.selftest.js` (66 checks) pass. - Scratch repro of the AB scenario (helper present but mode 0644): old code's last report is `{state:"nosignal"}` over a dead child; fixed code reports `Capture tool unavailable — see Admin / LTC capture failed to start: spawn … EACCES` once and nothing overwrites it. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
michael added 1 commit 2026-10-07 11:47:05 -04:00
When spawn() itself fails — EACCES on a helper that lost its execute
bit, as the 1.10.2 catalog install did on AB on 2026-10-04 — the child
emits 'error' with no 'exit' to follow. The handler reported the error
but left `child` set and scheduled nothing: the 250 ms eval loop then
kept reporting a misleading "No signal" over the dead child object, and
the listener was parked until a remount.

Null the child in the error handler and retry on the slow timer, the
way spl-listener already does (which is why SPL healed itself the
moment its binary was chmod +x'd, while Timers needed a remount). The
error report stays visible: the eval loop does not report while there
is no child.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Checking for merge conflicts…
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude/timers-ltc-spawn-error:claude/timers-ltc-spawn-error
git checkout claude/timers-ltc-spawn-error
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: michael/ProdDash#45