#23074: fix(synology-chat): prevent restart loop in startAccount
size: XL
Cluster:
Webhook Configuration and Resilience
## Summary
- **Problem:** The Synology Chat channel plugin enters a restart loop (exponential backoff, up to 10 attempts) immediately after starting
- **Root cause:** `startAccount` returns a synchronous `{ stop }` object. The gateway wraps the return value in `Promise.resolve()`, which resolves immediately. The gateway interprets this as a crash and triggers auto-restart.
- **Fix:** Replace the synchronous return with a `Promise<void>` that stays pending until `ctx.abortSignal` fires, keeping the channel alive until the gateway explicitly requests shutdown.
## Change Type
- [x] Bug fix
## Scope
- [x] Integrations (synology-chat extension only)
## What Changed
- `extensions/synology-chat/src/channel.ts`: `gateway.startAccount` now returns a pending Promise that resolves on `abortSignal`, instead of a synchronous `{ stop }` object
## Security Impact
- No security impact — only changes the lifecycle management of the channel plugin
## Repro + Verification
1. Start OpenClaw with Synology Chat enabled
2. **Before fix:** gateway logs show `auto-restart attempt 1/10`, `2/10`, etc. with exponential backoff
3. **After fix:** single startup log, no restart attempts
## Human Verification
- [x] Tested on Synology DS923+ with DSM 7.2
- [x] Single startup, no restart loop in logs
- [x] Bot responds correctly to DMs
- [x] Clean shutdown on `abortSignal`
## Compatibility
- Backward compatible: yes
- No config changes needed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed restart loop in Synology Chat channel by returning a pending Promise from `startAccount` instead of a synchronous object. The gateway wraps all returns in `Promise.resolve()`, so the old synchronous `{ stop }` return resolved immediately, triggering exponential backoff restarts.
**Critical Issues:**
- Incomplete fix: disabled/unconfigured accounts (lines 213, 220) still return synchronous `{ stop: () => {} }`, which will cause the same restart loop
- Tests are now incorrect: they expect `{ stop: function }` but the fix changes the return type to a pending Promise
**What works:**
- Properly configured accounts now return a pending Promise that only resolves when `abortSignal` fires
- Cleanup logic properly unregisters HTTP routes and removes event listeners
- Fix aligns with the gateway's expectation that `startAccount` returns a Promise that stays pending while the channel runs
<h3>Confidence Score: 2/5</h3>
- This PR has critical logical errors that will cause the same restart loop issue it claims to fix
- The fix is incomplete and partially incorrect. While it correctly addresses the restart loop for properly configured accounts (lines 287-299), it fails to apply the same fix to disabled/unconfigured accounts (lines 213, 220), which still return the synchronous `{ stop: () => {} }` that causes restart loops. Additionally, the tests are now incorrect and would fail to catch the incomplete fix since they still expect the old return type.
- extensions/synology-chat/src/channel.ts (lines 213, 220 must return pending Promise), extensions/synology-chat/src/channel.test.ts (tests expect wrong return type)
<sub>Last reviewed commit: ded2228</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#20554: fix(googlechat): prevent infinite restart loop in startAccount
by Gitjay11 · 2026-02-19
83.7%
#23621: fix(LINE): keep startAccount promise alive to prevent auto-restart ...
by ttakanawa · 2026-02-22
81.1%
#20395: fix(googlechat): prevent infinite auto-restart and ambiguous-target...
by ggalmeida0 · 2026-02-18
78.6%
#23134: fix(gateway): skip auto-restart for webhook channels that resolve i...
by puneet1409 · 2026-02-22
78.2%
#16736: fix: stagger multi-account channel startup to avoid Discord rate li...
by rm289 · 2026-02-15
77.8%
#22605: fix(msteams): keep provider promise pending until abort to stop aut...
by OpakAlex · 2026-02-21
76.1%
#19615: fix(discord): include default account when sub-accounts are configured
by prue-starfield · 2026-02-18
75.4%
#12953: fix: defer gateway restart until all replies are sent
by zoskebutler · 2026-02-10
75.2%
#23709: fix(synology-chat): resolve Chat API user_id for reply delivery
by druide67 · 2026-02-22
74.6%
#21956: fix(line): block monitorLineProvider on abort signal to prevent cra...
by lailoo · 2026-02-20
74.6%