openclaw - 💡(How to fix) Fix LaunchAgent: ThrottleInterval=1 causes unrecoverable gateway downtime after auto-update [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#60885Fetched 2026-04-08 02:46:07
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

The LaunchAgent plist template hardcodes ThrottleInterval: 1 and omits ExitTimeOut. Combined with the auto-update path using bootout (which removes the service from launchd entirely), this causes extended unrecoverable downtime when an update lands at the wrong moment.

Error Message

The update path runs bootout to stop the gateway before updating. bootout removes the service registration from launchd entirely. If the subsequent bootstrap fails for any reason (process tree killed, npm install error, disk full, etc.), the service stays unregistered and launchd will never restart it.

Root Cause

Root causes

Fix Action

Workaround

  1. Manually patch the plist after install:
    • ThrottleInterval from 1 to 10
    • Add ExitTimeOut: 20
  2. Always use openclaw gateway restart (not raw launchctl bootout)
  3. Pin or control update timing to avoid mid-flight npm updates

Code Example

<key>ThrottleInterval</key>
<integer>1</integer>

---

if ! launchctl kickstart -k ... ; then
  launchctl enable ...
  launchctl bootstrap ...
  launchctl kickstart -k ... || true
fi
RAW_BUFFERClick to expand / collapse

Summary

The LaunchAgent plist template hardcodes ThrottleInterval: 1 and omits ExitTimeOut. Combined with the auto-update path using bootout (which removes the service from launchd entirely), this causes extended unrecoverable downtime when an update lands at the wrong moment.

Environment

  • macOS 26.4 (arm64), Mac mini M4
  • OpenClaw 2026.4.2 (stable channel)
  • LaunchAgent service (ai.openclaw.gateway)
  • lossless-claw plugin 0.6.1

What happened

Crash #1 (8h53m downtime):

  1. Auto-update to 2026.4.2 triggered at 21:01 PDT on Apr 3
  2. npm i openclaw@latest ran in-place while gateway was live
  3. lossless-claw plugin failed to register during the mid-update file mismatch window (Unable to resolve plugin runtime module)
  4. Update flow called launchctl bootout to restart the gateway
  5. bootout removed the service from launchd entirely
  6. The follow-up bootstrap never completed (process tree died with the bootout)
  7. launchd logs confirm: removing service: ai.openclaw.gateway + job state = removed
  8. Gateway stayed dead from 21:02 until manual bootstrap at 05:55 next morning

Crash #2 (same day):

  1. Agent ran openclaw gateway restart which internally used bootout + bootstrap
  2. bootout at 06:27:48 removed the service again
  3. bootstrap at 06:28:24 re-registered it, gateway spawned (PID 65862)
  4. Gateway received SIGTERM 5 seconds later at 06:28:29 and exited after 10 seconds
  5. launchd respawned (PID 65900) successfully, but the gap caused user-visible downtime

Root causes

1. ThrottleInterval=1 is too aggressive

launchd-BPnToG40.js hardcodes:

<key>ThrottleInterval</key>
<integer>1</integer>

With ThrottleInterval: 1 and KeepAlive: true, if the gateway crashes and respawns repeatedly (e.g. during a plugin load failure), launchd treats it as thrashing and permanently stops restarting the service. The user must manually bootstrap + kickstart to recover.

Suggested fix: Change to <integer>10</integer> (or make it configurable). This gives the process enough time to stabilize on restart without triggering launchd's anti-thrash protection.

2. Missing ExitTimeOut

The plist template does not set ExitTimeOut. macOS defaults to 5 seconds, which is too tight for a gateway with active WebSocket connections. If the gateway doesn't exit within 5s of SIGTERM, launchd sends SIGKILL (confirmed in logs: Service did not exit 5 seconds after SIGTERM. Sending SIGKILL.).

Suggested fix: Add <key>ExitTimeOut</key><integer>20</integer> to the plist template.

3. Auto-update uses bootout (permanent service removal)

The update path runs bootout to stop the gateway before updating. bootout removes the service registration from launchd entirely. If the subsequent bootstrap fails for any reason (process tree killed, npm install error, disk full, etc.), the service stays unregistered and launchd will never restart it.

The detached restart handoff script in update-cli-qSRyEupZ.js already implements the correct pattern:

if ! launchctl kickstart -k ... ; then
  launchctl enable ...
  launchctl bootstrap ...
  launchctl kickstart -k ... || true
fi

But the stop command and some update paths still use bootout directly.

Suggested fix: Use kickstart -k as the primary restart mechanism everywhere. Reserve bootout only for openclaw gateway uninstall.

Impact

Any OpenClaw user running as a LaunchAgent on macOS is vulnerable to this. A single failed auto-update or plugin crash during startup can leave the gateway permanently dead until manual intervention. For headless/unattended deployments (Mac minis, build servers), this means hours of unnoticed downtime.

Workaround

  1. Manually patch the plist after install:
    • ThrottleInterval from 1 to 10
    • Add ExitTimeOut: 20
  2. Always use openclaw gateway restart (not raw launchctl bootout)
  3. Pin or control update timing to avoid mid-flight npm updates

extent analysis

TL;DR

Change the ThrottleInterval to a higher value, such as 10, and add an ExitTimeOut of 20 seconds to the LaunchAgent plist template to prevent extended downtime.

Guidance

  • Update the launchd-BPnToG40.js file to set ThrottleInterval to 10: <key>ThrottleInterval</key><integer>10</integer>.
  • Add ExitTimeOut to the plist template: <key>ExitTimeOut</key><integer>20</integer>.
  • Replace bootout with kickstart -k in the update path and restart mechanisms to prevent permanent service removal.
  • Manually patch the plist after install as a temporary workaround: update ThrottleInterval to 10 and add ExitTimeOut with a value of 20.

Example

The updated plist template should include:

<key>ThrottleInterval</key>
<integer>10</integer>
<key>ExitTimeOut</key>
<integer>20</integer>

Notes

These changes assume that the issue is primarily caused by the aggressive ThrottleInterval and missing ExitTimeOut values. Additional issues may still exist, and further debugging may be necessary.

Recommendation

Apply the workaround by manually patching the plist template and updating the ThrottleInterval and ExitTimeOut values. This should help prevent extended downtime until a more permanent fix can be implemented.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix LaunchAgent: ThrottleInterval=1 causes unrecoverable gateway downtime after auto-update [1 participants]