← Back to PRs

#23134: fix(gateway): skip auto-restart for webhook channels that resolve immediately

by puneet1409 open 2026-02-22 02:08 View on GitHub →
gateway size: XS
## Summary - Fix infinite auto-restart loop for webhook-based channels (Google Chat, BlueBubbles) introduced in v2026.2.17 - Track whether the channel task promise rejected and only auto-restart on error exit - Channels that resolve cleanly (webhook route registered successfully) are not restarted ## Problem The channel auto-restart hardening in v2026.2.17 wraps channel task promises with `.then(autoRestart)`. This fires when the promise **resolves**, not just when it rejects. **Polling channels** (Telegram, Discord, Slack) return long-lived promises that stay pending — their event loop runs forever. The `.then()` only fires when they crash. **Webhook channels** (Google Chat, BlueBubbles) register an HTTP route on the shared gateway server and resolve immediately — there is no long-running loop. The `.then()` fires right after startup, triggering an infinite restart cycle: ``` [googlechat] [fretron] starting Google Chat webhook [googlechat] [fretron] auto-restart attempt 1/10 in 5s [googlechat] [fretron] starting Google Chat webhook [googlechat] [fretron] auto-restart attempt 2/10 in 10s ... ``` ## Fix Add a `didError` flag set in the `.catch()` handler. The `.then()` auto-restart handler checks this flag and returns early if the channel exited cleanly (no error). This preserves crash-loop recovery for polling channels while preventing spurious restarts for webhook channels. ## Bisect | Version | Status | |---------|--------| | 2026.2.14 | OK | | 2026.2.15 | OK (last good) | | **2026.2.17** | **BROKEN** (first bad) | | 2026.2.19+ | BROKEN | ## Test plan - [x] Updated crash-loop test to use a throwing `startAccount` (simulates actual crash) - [x] Updated manual-stop test to use a throwing `startAccount` - [x] Added new test: webhook channel that resolves immediately is NOT restarted - [ ] Existing tests pass (`vitest run src/gateway/server-channels.test.ts`) Fixes #23114 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes infinite restart loop for webhook-based channels (specifically Google Chat) by tracking whether the channel task promise rejected before attempting auto-restart. The fix adds a `didError` flag that is set in the `.catch()` handler, and the `.then()` auto-restart handler checks this flag to skip restarting channels that exited cleanly. This preserves crash-loop recovery for long-running polling channels while preventing spurious restarts for webhook channels that resolve immediately after registering their HTTP route. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The fix is simple, well-tested, and directly addresses the root cause. The logic correctly distinguishes between clean exits and error exits using a boolean flag. Test coverage includes the new webhook behavior plus updated tests for crash-loop scenarios. The only minor issue is an inaccurate example in a code comment. - No files require special attention <sub>Last reviewed commit: c547db1</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs