Skip to content

fix: prevent launchd crash loop when dist/index.js is missing#220

Merged
kianwoon merged 2 commits intomainfrom
fix/launchd-crash-loop-pathstate
Apr 9, 2026
Merged

fix: prevent launchd crash loop when dist/index.js is missing#220
kianwoon merged 2 commits intomainfrom
fix/launchd-crash-loop-pathstate

Conversation

@kianwoon
Copy link
Copy Markdown
Owner

@kianwoon kianwoon commented Apr 9, 2026

Summary

  • Replace KeepAlive: true with KeepAlive: { PathState: { dist/index.js: true } } in the launchd plist
  • launchd now only restarts the daemon when the entry script actually exists on disk
  • Prevents the infinite crash loop that occurs when tsup cleans dist/ during a rebuild
  • When dist/index.js reappears after build, launchd automatically starts the daemon

Root cause

The crash happens before any of our code runs — Node's module loader fails with MODULE_NOT_FOUND when dist/index.js is missing. Since KeepAlive: true unconditionally restarts, this creates a tight crash loop (9 crashes observed in production).

Test plan

  • TypeScript compiles cleanly (npx tsc --noEmit)
  • All 22 daemon tests pass
  • Build succeeds (npm run build)
  • Verified plist template contains PathState instead of KeepAlive: true
  • Manual: delete dist/index.js, stop daemon → launchd should NOT restart
  • Manual: recreate dist/index.js → launchd should auto-start

Closes #216

kianwoon added 2 commits April 9, 2026 12:00
Use KeepAlive with PathState in launchd plist so launchd only
restarts the daemon when the entry script actually exists.

Closes #216
@kianwoon kianwoon merged commit 6e02977 into main Apr 9, 2026
5 checks passed
@kianwoon kianwoon deleted the fix/launchd-crash-loop-pathstate branch April 9, 2026 04:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: launchd crash loop when dist/index.js is missing

1 participant