← Back to PRs

#23074: fix(synology-chat): prevent restart loop in startAccount

by druide67 open 2026-02-22 00:17 View on GitHub →
size: XL
## 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