Bug
The gateway/health-monitor detects the Telegram channel as "stuck" during quiet periods (no messages for 30+ minutes) and attempts a restart. The restart path triggers a full gateway bind attempt on the main WebSocket port (18789), which fails with EADDRINUSE because the gateway already owns the port. This produces ~67 error log lines per cycle, repeating every 30 minutes indefinitely.
The MS Teams EADDRINUSE restart loop bugs were caused by the same pattern: channel restart cascading into a full gateway bind attempt. Those were fixed for MS Teams but the same bug exists in the Telegram channel restart path.
Reproduction
- Run OpenClaw gateway with Telegram channel enabled
- Wait 30+ minutes with no incoming Telegram messages
- Health monitor triggers:
[telegram:default] health-monitor: restarting (reason: stuck)
- Restart attempts to bind port 18789, fails with EADDRINUSE
- Cycle repeats every 30 minutes
Evidence
- Version: 2026.3.1
- Health monitor config: interval 300s (5 min), grace 60s
- Stale event threshold: 30 min (DEFAULT_STALE_EVENT_THRESHOLD_MS = 30 * 60000)
- Restart frequency: every ~30 min during quiet periods
- Error count: 2204 EADDRINUSE errors in 27 hours, 33 restart cycles
- Gateway is fully functional throughout - this is log spam, not a service outage
Log pattern per cycle
[telegram:default] health-monitor: restarting (reason: stuck)
[default] starting provider (@anika_openclaw_bot)
canvas host mounted at http://0.0.0.0:18789
Gateway is binding to a non-loopback address
Gateway failed to start: another gateway instance is already listening on ws://0.0.0.0:18789
Port 18789 is already in use.
- pid NNNN openclaw: openclaw-gateway (*:18789)
Root cause
channel-health-monitor.ts line ~1595: the isChannelHealthy() function treats a Telegram channel with no events for 30 min as unhealthy. For Telegram (long-polling), quiet periods with no messages are normal - unlike Slack WebSocket where a stale socket genuinely indicates a problem.
The restart calls channelManager.stopChannel() then channelManager.startChannel(). The startChannel path for Telegram appears to cascade into a full gateway initialization that attempts to bind the main port.
Suggested fixes
- Channel-specific stale thresholds: Telegram long-polling does not have the same stale-socket failure mode as Slack WebSocket. Either exempt Telegram from stale-event detection or use a much higher threshold (4h+)
- Port-ownership guard: Before attempting to bind during restart, check if the current process already owns the port. If so, skip the bind
- Channel-only restart: The restart path should reinitialise only the channel provider, not the full gateway
Workaround
gateway.channelHealthCheckMinutes: 0 in openclaw.json disables the health monitor entirely. This works but removes the safety net for genuinely stuck channels.
Related issues
Bug
The
gateway/health-monitordetects the Telegram channel as "stuck" during quiet periods (no messages for 30+ minutes) and attempts a restart. The restart path triggers a full gateway bind attempt on the main WebSocket port (18789), which fails with EADDRINUSE because the gateway already owns the port. This produces ~67 error log lines per cycle, repeating every 30 minutes indefinitely.Same class as #22169, #24522, #25527
The MS Teams EADDRINUSE restart loop bugs were caused by the same pattern: channel restart cascading into a full gateway bind attempt. Those were fixed for MS Teams but the same bug exists in the Telegram channel restart path.
Reproduction
[telegram:default] health-monitor: restarting (reason: stuck)Evidence
Log pattern per cycle
Root cause
channel-health-monitor.tsline ~1595: theisChannelHealthy()function treats a Telegram channel with no events for 30 min as unhealthy. For Telegram (long-polling), quiet periods with no messages are normal - unlike Slack WebSocket where a stale socket genuinely indicates a problem.The restart calls
channelManager.stopChannel()thenchannelManager.startChannel(). ThestartChannelpath for Telegram appears to cascade into a full gateway initialization that attempts to bind the main port.Suggested fixes
Workaround
gateway.channelHealthCheckMinutes: 0in openclaw.json disables the health monitor entirely. This works but removes the safety net for genuinely stuck channels.Related issues