.claude/skills/openclaw-upgrade-plist-overwrite/SKILL.md
Fix OpenClaw gateway crash-looping after npm upgrade overwrites LaunchAgent plist. Use when: (1) Gateway exits with code 1 after `npm install -g openclaw`, (2) gateway.err.log shows MissingEnvVarError for BLUEBUBBLES_PASSWORD or other secrets, (3) LaunchAgent plist ProgramArguments changed from wrapper script to direct node execution, (4) `openclaw install --service` ran as post-install hook and replaced the plist. Covers diagnosis, fix, and safeguard for future upgrades.
npx skillsauth add Dbochman/dotfiles openclaw-upgrade-plist-overwriteInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
npm install -g openclaw runs openclaw install --service as a post-install hook,
which overwrites ~/Library/LaunchAgents/ai.openclaw.gateway.plist. The new plist
uses direct node execution with inline EnvironmentVariables but is missing secrets
like BLUEBUBBLES_PASSWORD that the wrapper script sources from ~/.openclaw/.secrets-cache.
This causes the gateway to crash-loop with exit code 1.
launchctl list | grep openclaw shows non-zero exit code~/.openclaw/logs/gateway.err.log contains MissingEnvVarError or config parse errorsProgramArguments points to /opt/homebrew/opt/node@22/bin/node directly instead of the wrapper appThe openclaw install --service post-install hook:
/opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/entry.js gatewayEnvironmentVariables dict~/.openclaw/.secrets-cache (e.g., BLUEBUBBLES_PASSWORD, OP_SERVICE_ACCOUNT_TOKEN)The wrapper script at ~/Applications/OpenClawGateway.app/Contents/MacOS/OpenClawGateway
sources all secrets from .secrets-cache before exec'ing node, which is the correct pattern
for headless launchd services (no biometric/1Password available).
ssh dylans-mac-mini 'launchctl list | grep openclaw.gateway'
Non-zero exit code (e.g., 1) confirms crash.
ssh dylans-mac-mini 'tail -50 ~/.openclaw/logs/gateway.err.log'
Look for MissingEnvVarError, Config invalid, or env var substitution failures like
${BLUEBUBBLES_PASSWORD} appearing literally in config.
ssh dylans-mac-mini 'plutil -p ~/Library/LaunchAgents/ai.openclaw.gateway.plist'
If ProgramArguments contains /opt/homebrew/opt/node@22/bin/node instead of the
wrapper path (~/Applications/OpenClawGateway.app/Contents/MacOS/OpenClawGateway),
the plist was overwritten.
New OpenClaw versions may change the entry point (e.g., dist/index.js to dist/entry.js).
Check what the new plist points to and update the wrapper:
# Check new entry point from the overwritten plist
ssh dylans-mac-mini 'plutil -p ~/Library/LaunchAgents/ai.openclaw.gateway.plist | grep entry'
# Update wrapper script's exec line
ssh dylans-mac-mini 'cat ~/Applications/OpenClawGateway.app/Contents/MacOS/OpenClawGateway'
# Edit the exec line to use the correct dist/*.js path
Replace the overwritten plist with the wrapper-based version:
ssh dylans-mac-mini "cat > ~/Library/LaunchAgents/ai.openclaw.gateway.plist << 'PLIST'
<?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.gateway</string>
<key>ProgramArguments</key>
<array>
<string>/Users/dbochman/Applications/OpenClawGateway.app/Contents/MacOS/OpenClawGateway</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/dbochman/.openclaw/logs/gateway.log</string>
<key>StandardErrorPath</key>
<string>/Users/dbochman/.openclaw/logs/gateway.err.log</string>
</dict>
</plist>
PLIST"
ssh dylans-mac-mini 'launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist 2>/dev/null; launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist'
ssh dylans-mac-mini 'sleep 3 && launchctl list | grep openclaw.gateway'
Exit code should be 0. Check logs:
ssh dylans-mac-mini 'tail -5 ~/.openclaw/logs/gateway.log'
The ~/bin/openclaw-weekly-upgrade script on Mini should backup/restore the plist
around npm install:
# Before npm install
PLIST="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PLIST_BAK="/tmp/openclaw-gateway-plist-backup.plist"
cp "$PLIST" "$PLIST_BAK"
# npm install happens here
/opt/homebrew/opt/node@22/bin/npm install -g openclaw@latest
# After npm install — restore plist
if ! diff -q "$PLIST_BAK" "$PLIST" > /dev/null 2>&1; then
cp "$PLIST_BAK" "$PLIST"
echo "WARN: plist was overwritten by npm install, restored from backup"
fi
launchctl list | grep openclaw.gateway shows exit code 0tail ~/.openclaw/logs/gateway.err.log has no MissingEnvVarErrorplutil -p ~/Library/LaunchAgents/ai.openclaw.gateway.plist shows wrapper path in ProgramArguments~/.openclaw/.secrets-cache which contains BLUEBUBBLES_PASSWORD,
OP_SERVICE_ACCOUNT_TOKEN, and other secrets in KEY=VALUE format (chmod 600)dist/index.js to dist/entry.js in v2026.3.2 — check
the installed version's actual entry point if wrapper fails after upgradeopenclaw install --service hook cannot be disabled via npm flagslaunchctl bootout + bootstrap is required (not just kickstart) to pick up plist changesopenclaw.json config changes but plist changes require full service reloadtools
Use exact configured Reolink cameras through the local Home Hub for availability and power status, fresh stills, visual commentary, protected Dylan/Julia/household sharing, and reversible spotlight control. Supports trusted owner tasks and explicitly scoped proactive automations; not for Nest or Ring cameras, arbitrary recipients, recordings, account changes, or raw camera APIs.
data-ai
Privately manage Dylan and Julia's household plant inventory and care history by physical location, bed, and exact Flower Cam view. Use for confirmed plant onboarding from camera conversations, camera- or bed-filtered inventory, record corrections, individual or whole-bed care, and private filtered exports. Pair with reolink-camera when an owner asks about plants visible in Flower Cam images.
testing
Inspect and control the physically secured Reachy Mini at Crosstown through ClawBody. Use for requests to check Reachy, look around, express an emotion, play any official emotion or dance preset, speak proactively, mute or unmute its microphone, stop movement, or describe what its camera sees.
tools
Handle Reachy/iMessage handoffs, selective durable memory, forgetting, and diagnostics; automatic context comes from the gateway plugin.