openclaw - 💡(How to fix) Fix openclaw update post-restart port check still races on the version-change path (regression scope of #78699 / PR #79719)

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…

openclaw update exits with non-zero status and prints Gateway already running locally. Stop it (openclaw gateway stop) or use a different port. when the package update actually succeeded and the new gateway is healthy. The same-version refresh path (introduced by #79719) correctly detects the already-running new version and skips the redundant restart, but the version-change path (e.g. 2026.5.7 → 2026.5.20) still hits the original race described in #78699.

Reference: #78699 (closed); PR #79719 (merged 2026-05-09); wdeveloper16's comment on #78699 noting that the update path in run-loop.ts exits via exitProcess(0) and does not go through stopLaunchAgent, so the port conflict race is independent of [#78412] and needs a targeted fix in src/cli/update-cli/restart-helper.ts / run-loop.ts.

Error Message

make: *** [up] Error 1

Root Cause

The PR #79719 logic that detects "already serving the expected version" doesn't reach this code path on version changes because of the configured-vs-runtime version skew during the in-flight bootout window.

Fix Action

Fix / Workaround

Local workaround applied

Code Example

Stopping managed gateway service before package update...
Warning: launchctl stop did not fully stop the service; used bootout fallback and left service unloaded
Stopped LaunchAgent (degraded): gui/508/ai.openclaw.gateway
◇ ✓ Updating via package manager (25.83s)
◇ ✓ Running doctor checks (42.99s)
Update Result: OK
  Root: /usr/local/lib/node_modules/openclaw
  Before: 2026.5.7
  After: 2026.5.20

Restarting service...
Config was last written by a newer OpenClaw (2026.5.20); current version is 2026.5.7.
Gateway did not become healthy after restart.
Service runtime: status=running, state=active, pid=12425
Port 18789 is already in use.
- pid 12425 val: /usr/local/opt/node/bin/node /usr/local/lib/node_modules/openclaw/dist/index.js gateway --port 18789 (127.0.0.1:18789)
- Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
Restart log: /Users/val/.openclaw/logs/gateway-restart.log
Run `openclaw gateway status --deep` for details.

make: *** [up] Error 1

---

Gateway already reports the updated version after service refresh; skipped redundant restart.
Gateway: restarted and verified.

---

openclaw update     # while transitioning to a newer version
# exits non-zero with "Port 18789 is already in use"
curl http://127.0.0.1:18789/healthz   # actually healthy

---

up:
	@openclaw update; rc=$$?; \
	if curl -sf -m 10 http://127.0.0.1:18789/healthz > /dev/null 2>&1; then \
	  if [ $$rc -ne 0 ]; then echo "(note: openclaw update exited $$rc, but gateway /healthz is OK — treating as success)"; fi; \
	  exit 0; \
	else exit $$rc; fi
RAW_BUFFERClick to expand / collapse

Summary

openclaw update exits with non-zero status and prints Gateway already running locally. Stop it (openclaw gateway stop) or use a different port. when the package update actually succeeded and the new gateway is healthy. The same-version refresh path (introduced by #79719) correctly detects the already-running new version and skips the redundant restart, but the version-change path (e.g. 2026.5.7 → 2026.5.20) still hits the original race described in #78699.

Reference: #78699 (closed); PR #79719 (merged 2026-05-09); wdeveloper16's comment on #78699 noting that the update path in run-loop.ts exits via exitProcess(0) and does not go through stopLaunchAgent, so the port conflict race is independent of [#78412] and needs a targeted fix in src/cli/update-cli/restart-helper.ts / run-loop.ts.

Observed (2026-05-22, macOS)

make up invoking openclaw update from 2026.5.7 → 2026.5.20:

Stopping managed gateway service before package update...
Warning: launchctl stop did not fully stop the service; used bootout fallback and left service unloaded
Stopped LaunchAgent (degraded): gui/508/ai.openclaw.gateway
◇ ✓ Updating via package manager (25.83s)
◇ ✓ Running doctor checks (42.99s)
Update Result: OK
  Root: /usr/local/lib/node_modules/openclaw
  Before: 2026.5.7
  After: 2026.5.20

Restarting service...
Config was last written by a newer OpenClaw (2026.5.20); current version is 2026.5.7.
Gateway did not become healthy after restart.
Service runtime: status=running, state=active, pid=12425
Port 18789 is already in use.
- pid 12425 val: /usr/local/opt/node/bin/node /usr/local/lib/node_modules/openclaw/dist/index.js gateway --port 18789 (127.0.0.1:18789)
- Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
Restart log: /Users/val/.openclaw/logs/gateway-restart.log
Run `openclaw gateway status --deep` for details.

make: *** [up] Error 1

Verification right after that output:

  • curl -sf http://127.0.0.1:18789/healthz{"ok":true,"status":"live"}
  • openclaw status → gateway 2026.5.20, all channels OK, pid 12425, state active
  • The "Gateway already running locally" message is reporting the newly-spawned healthy gateway process as the conflict.

Re-running make up on the now-current 2026.5.20 (i.e., no-op version) correctly hits the PR #79719 path:

Gateway already reports the updated version after service refresh; skipped redundant restart.
Gateway: restarted and verified.

Exit 0. So #79719's fix works for the same-version refresh, not for the version-change upgrade.

Why it still races

PR #79719's restart-skip check happens in the same code path that also runs the redundant restart attempt. On a version change, the update script:

  1. Bootouts the old LaunchAgent (succeeds; "left service unloaded").
  2. Updates the npm package.
  3. The LaunchAgent's KeepAlive: true (+ ThrottleInterval: 1 originally, now widened by #79719) respawns the gateway against port 18789 before the update script's restart logic runs.
  4. The script then tries its own restart, finds port 18789 occupied (by the LaunchAgent-respawned new gateway), and reports "Gateway already running locally".

The PR #79719 logic that detects "already serving the expected version" doesn't reach this code path on version changes because of the configured-vs-runtime version skew during the in-flight bootout window.

Reproduction

Pre-2026.5.20 OpenClaw on macOS LaunchAgent with KeepAlive: true:

openclaw update     # while transitioning to a newer version
# exits non-zero with "Port 18789 is already in use"
curl http://127.0.0.1:18789/healthz   # actually healthy

Expected

The script should either:

  • Apply PR #79719's "already-serving-the-expected-version" check after the version metadata is updated, so a respawned new-version gateway is recognized as a successful restart, OR
  • launchctl bootout and keep the service unloaded during the update window so launchd doesn't pre-empt the script's restart, OR
  • Probe /healthz + report version with timeout before declaring failure on port-in-use.

Local workaround applied

Makefile shim that uses /healthz as the source of truth:

up:
	@openclaw update; rc=$$?; \
	if curl -sf -m 10 http://127.0.0.1:18789/healthz > /dev/null 2>&1; then \
	  if [ $$rc -ne 0 ]; then echo "(note: openclaw update exited $$rc, but gateway /healthz is OK — treating as success)"; fi; \
	  exit 0; \
	else exit $$rc; fi

Environment

  • macOS 26.4.1 (Darwin 25.4.0, x64)
  • node 22.22.0
  • Package manager: pnpm-installed, ran via openclaw update
  • LaunchAgent path: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
  • Plist: KeepAlive=true, ThrottleInterval=10 (already widened from the PR #79719 default)
  • Pre-update version: 2026.5.7
  • Post-update version: 2026.5.20 (current 2026.5.20 confirmed via openclaw status)

Notes

  • Same family as still-open #85133 ("Gateway launchd agent gets unloaded during self-update and never re-bootstrapped"). That issue is more dangerous (full outage); this one is "cosmetic but breaks any CI/Makefile that trusts the exit code."
  • The accompanying log ~/.openclaw/logs/gateway-restart.log shows the underlying restart as restart done source=update — i.e., the restart layer thinks it succeeded; the disagreement is between the restart layer and the outer wrapper's port-check.

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 openclaw update post-restart port check still races on the version-change path (regression scope of #78699 / PR #79719)