#20554: fix(googlechat): prevent infinite restart loop in startAccount
channel: googlechat
size: XS
Cluster:
Webhook Configuration and Resilience
## Summary
- Problem: The startAccount function in the Google Chat plugin resolved immediately after registering the webhook handler.
- Why it matters: The OpenClaw gateway interprets any resolution of this promise as the channel "stopping," triggering an infinite auto-restart loop every 5-10 seconds.
- What changed: Updated startAccount to stay pending by awaiting the abortSignal. This ensures the gateway sees the channel as "running" for its entire lifecycle.
- What did NOT change (scope boundary): Did not modify the webhook server, message processing logic, or authentication flows.
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [x] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes #20502
## User-visible / Behavior Changes
None
## Security Impact (required)
- New permissions/capabilities? (`No`)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
## Repro + Verification
### Environment
- OS: Windows / Ubuntu Linux
- Runtime/container: Node.js 22
- Integration/channel (if any): Google Chat
### Steps
1. Configure Google Chat account.
2. Start the gateway (npm start).
3. Check logs for "auto-restart attempt" loops.
### Expected
- The plugin starts once and remains active.
### Actual
- The plugin enters an infinite restart loop and eventually gives up after 10 attempts.
## Evidence
Infinite restart loop observed before fix:
```
[googlechat] starting Google Chat webhook
[googlechat] auto-restart attempt 1/10 in 5s
[googlechat] starting Google Chat webhook
[googlechat] auto-restart attempt 2/10 in 10s
...
[googlechat] giving up after 10 restart attempts
```
After fix: Verified that the startAccount promise stays pending during normal execution, keeping the status as "Running" and preventing the automatic restart cycle.
## Human Verification (required)
- Verified scenarios: Manually confirmed that startAccount promise stays pending during operation and resolves only when the system is shut down (abortSignal triggers).
- Edge cases checked: Verified that if the signal is already aborted, the function returns immediately without hanging.
- What you did not verify: Webhook payload delivery (unchanged logic).
## Compatibility / Migration
- Backward compatible? (`Yes`)
- Config/env changes? (`No`)
- Migration needed? (`No`)
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly: Revert changes in extensions/googlechat/src/channel.ts
- Known bad symptoms reviewers should watch for: Hanging during shutdown if the signal listener fails.
## Risks and Mitigations
None
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed critical bug where Google Chat channel entered infinite restart loop. The `startAccount` function was returning immediately after registering the webhook handler because `startGoogleChatMonitor` returns a cleanup function synchronously. The gateway's auto-restart logic interprets any promise resolution as the channel "stopping" (see `src/gateway/server-channels.ts:203-248`), triggering restart attempts every 5-10 seconds until giving up after 10 attempts. The fix makes the promise stay pending by awaiting the `abortSignal`, which is the correct lifecycle pattern - the channel stays "running" until the system initiates shutdown.
<h3>Confidence Score: 5/5</h3>
- Safe to merge - correctly fixes infinite restart loop with standard pattern
- The fix correctly implements the lifecycle pattern used by webhook-based channel plugins. The change makes `startAccount` stay pending until shutdown by awaiting the `abortSignal`, matching how the gateway expects long-running channels to behave. The code includes proper cleanup (`unregister?.()`) and status updates, and handles the edge case where the signal is already aborted. This is a minimal, targeted fix with no risk of introducing new issues.
- No files require special attention
<sub>Last reviewed commit: d270b67</sub>
<!-- greptile_other_comments_section -->
<sub>(5/5) You can turn off certain types of comments like style [here](https://app.greptile.com/review/github)!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#20395: fix(googlechat): prevent infinite auto-restart and ambiguous-target...
by ggalmeida0 · 2026-02-18
87.1%
#23134: fix(gateway): skip auto-restart for webhook channels that resolve i...
by puneet1409 · 2026-02-22
84.2%
#23074: fix(synology-chat): prevent restart loop in startAccount
by druide67 · 2026-02-22
83.7%
#22322: fix(googlechat): keep webhook monitor alive until abort
by AIflow-Labs · 2026-02-21
83.2%
#20551: fix(googlechat): prevent health monitor restart loop and add JWT ve...
by FredCat32 · 2026-02-19
82.3%
#19043: googlechat: fix runtime.error signature in startup error handling
by markesphere · 2026-02-17
82.0%
#23621: fix(LINE): keep startAccount promise alive to prevent auto-restart ...
by ttakanawa · 2026-02-22
81.5%
#15643: fix(googlechat): DM's works, but groups don't - return add-on actio...
by kamil-rudnicki · 2026-02-13
78.9%
#22605: fix(msteams): keep provider promise pending until abort to stop aut...
by OpakAlex · 2026-02-21
78.4%
#22182: fix(msteams): prevent false auto-restart loop after successful startup
by pandego · 2026-02-20
77.6%