Appearance
OpenClaw macOS LaunchAgent 重启后 bootstrap 未执行导致 Gateway 永久停止
问题
在 macOS 上通过 LaunchAgent(plist)管理 OpenClaw Gateway 时,update.run 触发内部重启后,launchctl bootout 执行成功但 launchctl bootstrap 从未运行,Gateway 进程永久消失:
[gui/501/ai.openclaw.gateway]: removing service: ai.openclaw.gateway即使配置了 KeepAlive: true,Gateway 也不会自动恢复——因为 bootout 之后服务已从 launchd 注销,launchd 对它毫不知情。
典型场景:凌晨 4:00 openclaw update 自动更新成功,早上 11:30 Gateway 内部触发一次重启,bootout 成功、bootstrap 失败,Gateway 死了 2 小时多直到手动干预。
根本原因:OpenClaw 的 update/restart 流程执行 launchctl bootout 和 launchctl bootstrap 之间存在竞态窗口——若子进程链意外断开(node → zsh → node 的调用链中任何一环退出),bootstrap 步骤被跳过,没有恢复机制。ThrottleInterval: 1 过小也可能导致 launchd 认为服务在短时间内异常退出并拒绝立即重新注册。
解决方案
方案一:增大 ThrottleInterval(防止 launchd 拒绝快速重注册)
在 ~/Library/LaunchAgents/ai.openclaw.gateway.plist 中调整:
xml
<key>ThrottleInterval</key>
<integer>10</integer>调整后重新加载 plist:
bash
launchctl unload ~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl load ~/Library/LaunchAgents/ai.openclaw.gateway.plist方案二:添加看门狗脚本(补偿 bootstrap 缺失)
创建 ~/Library/LaunchAgents/ai.openclaw.watchdog.plist:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.openclaw.watchdog</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>
if ! launchctl list | grep -q ai.openclaw.gateway; then
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist
fi
</string>
</array>
<key>StartInterval</key>
<integer>60</integer>
</dict>
</plist>bash
launchctl load ~/Library/LaunchAgents/ai.openclaw.watchdog.plist每分钟检测一次 Gateway 是否还注册在 launchd 中,丢失则自动 bootstrap。
方案三:紧急恢复命令
若 Gateway 已消失,立即执行:
bash
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist诊断确认
验证 Gateway 是否还在 launchd 注册:
bash
launchctl list | grep openclaw
# 有输出 = 已注册;无输出 = 需要手动 bootstrap常见问题
Q: KeepAlive: true 为什么没有帮助?
A: KeepAlive 依赖 launchd 知道该服务存在。bootout 成功执行后,服务从 launchd 的注册表中彻底删除,launchd 无法"保持存活"一个它不认识的服务。
Q: 这个问题在 Linux(systemd)上也会发生吗?
A: 不会。systemd 的 Restart=always 即使在 stop 后重新注册也有完善的事务保障;macOS launchd 的 bootout/bootstrap 两步操作没有原子性保证,是 macOS 特有问题。
Q: 升级到最新 OpenClaw 版本能否修复?
A: 关注 GitHub #40089,官方尚无修复。建议在修复发布前部署方案二(看门狗脚本)作为长期防护。