Bug type
Regression / macOS launchd lifecycle bug
Summary
After updating to 2026.5.12, a submitted manual update launchd job kept relaunching even though the updater script had completed successfully (last exit code = 0). Each relaunch stopped/started the gateway, causing repeated clean SIGTERM shutdowns every few minutes.
During that churn, Telegram direct messages were received/spooled and the Telegram update offset advanced, but the messages did not appear in the active session transcript and no normal agent reply completed. From the user perspective, Telegram messages were being swallowed.
This looks related to the general launchd restart-loop class in #73673, but this report is specifically about a submitted manual update job with inferred keepalive behavior, not the main ai.openclaw.gateway LaunchAgent crashing on startup.
Environment
- OpenClaw:
2026.5.12 (f066dd2)
- macOS:
26.4.1 (25E253), Apple Silicon / arm64
- Node:
v25.9.0
- Install: npm global under Homebrew Node
- Gateway service: macOS LaunchAgent
ai.openclaw.gateway, command:
/opt/homebrew/opt/node/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 18789
- Gateway bind: loopback, port
18789
- Telegram: bot channel, polling mode
Observed behavior
Telegram history showed the bot responding to earlier messages, then later only sending repeated watchdog/progress acknowledgements like “Got it. Working on message ...; The turn is still active,” without completing the actual turns.
Local evidence showed the Telegram updates existed in the local ingress spool and update-offset-default.json had advanced past them, but the corresponding direct session transcript under ~/.openclaw/agents/main/sessions/*.jsonl did not contain those user messages.
The gateway logs showed repeated startup followed by clean SIGTERM shutdowns. Example pattern:
[gateway] http server listening ...
[telegram] [default] starting provider (...)
[telegram] Inbound message telegram:<redacted-user-id> -> <redacted-bot> (direct, 178 chars)
[gateway] signal SIGTERM received
[gateway] received SIGTERM; shutting down
[shutdown] completed cleanly ...
The root local finding was this submitted launchd job:
launchctl print gui/$(id -u)/ai.openclaw.manual-update-2026-05-14-2026-5-12
Key redacted fields:
type = Submitted
state = running
program = /Users/<user>/.openclaw/workspace/tmp/openclaw-update-2026-05-14.sh
runs = 4843
last exit code = 0
properties = keepalive | inferred program
The updater script was a one-shot update helper that stopped the gateway, ran an OpenClaw update to 2026.5.12, restarted the gateway, and checked health. It appears to have succeeded, but launchd continued relaunching it because of inferred keepalive behavior.
Recovery performed locally
The machine was recovered by booting out the submitted manual update job:
launchctl bootout gui/$(id -u)/ai.openclaw.manual-update-2026-05-14-2026-5-12
After that:
launchctl list no longer showed the manual update job
ai.openclaw.gateway stayed running
openclaw gateway status --json reported the LaunchAgent active/running
openclaw channels status --json reported Telegram configured/running/connected in polling mode
- No further repeated gateway SIGTERM loop was observed during the follow-up window
Current recovered service state:
ai.openclaw.gateway pid=<redacted> status=running
manual update launchd job absent from launchctl list
telegram channel configured=true running=true connected=true mode=polling
Expected behavior
A manual/update helper submitted to launchd should not be left in a relaunching state after successful completion. A successful updater should either:
- avoid inferred/implicit KeepAlive semantics entirely, or
- explicitly unload/bootout its submitted launchd job when done, or
- use a launchd policy that does not relaunch on successful exit.
Separately, Telegram spool/offset handling should avoid advancing irreversibly past an inbound update until the update is durably persisted/routed into the target session, or should provide a recovery/replay path when the gateway is killed during processing.
Actual behavior
The successful updater job had run thousands of times with last exit code = 0, repeatedly stopping/restarting the gateway. Telegram inbound updates during that period were consumed from Telegram’s perspective but did not complete as normal session turns.
Impact
High for macOS users using Telegram and launchd-managed gateway updates:
- gateway repeatedly goes down/up despite a successful update
- Telegram messages can appear received but go unanswered
- Telegram update offset can advance, making the missed messages non-obvious to replay
- cron jobs and watchdogs can pile up during the churn
- user-visible symptom is “bot is alive enough to acknowledge/progress, but real messages are swallowed”
Related issues
Additional notes
I intentionally did not include tokens, bot credentials, full user IDs, the full OpenClaw config, or raw Telegram spool JSON. The local evidence above was enough to identify and stop the relaunch loop without exposing secrets.
Reported on behalf of Doug Butdorf after recovering the affected macOS node.
Bug type
Regression / macOS launchd lifecycle bug
Summary
After updating to
2026.5.12, a submitted manual update launchd job kept relaunching even though the updater script had completed successfully (last exit code = 0). Each relaunch stopped/started the gateway, causing repeated cleanSIGTERMshutdowns every few minutes.During that churn, Telegram direct messages were received/spooled and the Telegram update offset advanced, but the messages did not appear in the active session transcript and no normal agent reply completed. From the user perspective, Telegram messages were being swallowed.
This looks related to the general launchd restart-loop class in #73673, but this report is specifically about a submitted manual update job with inferred keepalive behavior, not the main
ai.openclaw.gatewayLaunchAgent crashing on startup.Environment
2026.5.12 (f066dd2)26.4.1 (25E253), Apple Silicon /arm64v25.9.0ai.openclaw.gateway, command:/opt/homebrew/opt/node/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 1878918789Observed behavior
Telegram history showed the bot responding to earlier messages, then later only sending repeated watchdog/progress acknowledgements like “Got it. Working on message ...; The turn is still active,” without completing the actual turns.
Local evidence showed the Telegram updates existed in the local ingress spool and
update-offset-default.jsonhad advanced past them, but the corresponding direct session transcript under~/.openclaw/agents/main/sessions/*.jsonldid not contain those user messages.The gateway logs showed repeated startup followed by clean SIGTERM shutdowns. Example pattern:
The root local finding was this submitted launchd job:
Key redacted fields:
The updater script was a one-shot update helper that stopped the gateway, ran an OpenClaw update to
2026.5.12, restarted the gateway, and checked health. It appears to have succeeded, but launchd continued relaunching it because of inferred keepalive behavior.Recovery performed locally
The machine was recovered by booting out the submitted manual update job:
launchctl bootout gui/$(id -u)/ai.openclaw.manual-update-2026-05-14-2026-5-12After that:
launchctl listno longer showed the manual update jobai.openclaw.gatewaystayed runningopenclaw gateway status --jsonreported the LaunchAgent active/runningopenclaw channels status --jsonreported Telegram configured/running/connected in polling modeCurrent recovered service state:
Expected behavior
A manual/update helper submitted to launchd should not be left in a relaunching state after successful completion. A successful updater should either:
Separately, Telegram spool/offset handling should avoid advancing irreversibly past an inbound update until the update is durably persisted/routed into the target session, or should provide a recovery/replay path when the gateway is killed during processing.
Actual behavior
The successful updater job had run thousands of times with
last exit code = 0, repeatedly stopping/restarting the gateway. Telegram inbound updates during that period were consumed from Telegram’s perspective but did not complete as normal session turns.Impact
High for macOS users using Telegram and launchd-managed gateway updates:
Related issues
openclaw gateway restartfails to re-bootstrap LaunchAgent on macOS #40905: prior macOS launchd restart lifecycle instabilityAdditional notes
I intentionally did not include tokens, bot credentials, full user IDs, the full OpenClaw config, or raw Telegram spool JSON. The local evidence above was enough to identify and stop the relaunch loop without exposing secrets.
Reported on behalf of Doug Butdorf after recovering the affected macOS node.