openclaw - 💡(How to fix) Fix Gateway restart race condition: kickstart -k fails when process already terminated by SIGTERM [1 comments, 2 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#50035Fetched 2026-04-08 01:00:03
View on GitHub
Comments
1
Participants
2
Timeline
1
Reactions
0
Author
Timeline (top)
commented ×1

Fix Action

Fix / Workaround

When config.patch or config.apply triggers a gateway restart on macOS (launchd), the gateway frequently fails to come back up. The restart mechanism sends SIGTERM to the process group, then attempts launchctl kickstart -k on the service — but by the time kickstart runs, the process is already dead and the LaunchAgent is in a stopped/unloaded state. The bootstrap fallback also silently fails, leaving the gateway permanently down until manual intervention (openclaw doctor).

  1. Have gateway running via launchd (ai.openclaw.gateway LaunchAgent, KeepAlive: true)
  2. Apply a config change that triggers restart (e.g. config.patch adding a model provider)
  3. Gateway receives SIGTERM at the expected time, shuts down cleanly
  4. Gateway never comes back up

Code Example

2026-03-18T12:52:21.365-05:00 [gateway] signal SIGTERM received
2026-03-18T12:52:21.366-05:00 [gateway] received SIGTERM; shutting down
2026-03-18T12:52:21.372-05:00 [gmail-watcher] gmail watcher stopped
RAW_BUFFERClick to expand / collapse

Bug Description

When config.patch or config.apply triggers a gateway restart on macOS (launchd), the gateway frequently fails to come back up. The restart mechanism sends SIGTERM to the process group, then attempts launchctl kickstart -k on the service — but by the time kickstart runs, the process is already dead and the LaunchAgent is in a stopped/unloaded state. The bootstrap fallback also silently fails, leaving the gateway permanently down until manual intervention (openclaw doctor).

Reproduction Steps

  1. Have gateway running via launchd (ai.openclaw.gateway LaunchAgent, KeepAlive: true)
  2. Apply a config change that triggers restart (e.g. config.patch adding a model provider)
  3. Gateway receives SIGTERM at the expected time, shuts down cleanly
  4. Gateway never comes back up

Expected Behavior

Gateway should reliably restart after config-triggered SIGTERM, either via kickstart -k or the bootstrap fallback.

Actual Behavior

Gateway stays dead. The restart flow in restart-B-xYDDdI.js appears to:

  1. Call cleanStaleGatewayProcessesSync() → kills process group with SIGTERM
  2. Call launchctl kickstart -k gui/<uid>/ai.openclaw.gateway → fails (service already dead)
  3. Fall back to launchctl bootstrap gui/<uid> <plist-path> → also fails silently

From gateway.log:

2026-03-18T12:52:21.365-05:00 [gateway] signal SIGTERM received
2026-03-18T12:52:21.366-05:00 [gateway] received SIGTERM; shutting down
2026-03-18T12:52:21.372-05:00 [gmail-watcher] gmail watcher stopped

No further gateway log entries until manual recovery ~2 hours later.

Possible Fix

The restart logic should handle the case where the process is already terminated before kickstart -k runs. Options:

  • Add a brief delay/poll between SIGTERM and kickstart to confirm the process has exited and launchd has updated its state
  • Use launchctl bootout + launchctl bootstrap as the primary restart path instead of kickstart -k (explicit unload/reload)
  • Retry bootstrap with a short backoff if the first attempt fails

Environment

  • macOS 15 (arm64, Apple Silicon)
  • Node.js v25.6.1
  • OpenClaw v2026.3.7
  • LaunchAgent with KeepAlive: true, ThrottleInterval: 1

extent analysis

Fix Plan

To address the issue, we will implement a brief delay between sending the SIGTERM signal and attempting to restart the gateway using launchctl kickstart -k. This delay will ensure that the process has exited and launchd has updated its state before attempting to restart.

Code Changes

We will modify the restart-B-xYDDdI.js script to include a delay before calling launchctl kickstart -k. We can use the setTimeout function to introduce a delay of 1-2 seconds.

// ...

// Call cleanStaleGatewayProcessesSync to kill the process group with SIGTERM
cleanStaleGatewayProcessesSync();

// Introduce a delay before attempting to restart
setTimeout(() => {
  // Call launchctl kickstart -k to restart the gateway
  launchctlKickstart();
}, 1500); // 1.5 second delay

// ...

function launchctlKickstart() {
  // Call launchctl kickstart -k gui/<uid>/ai.openclaw.gateway
  // ...
}

Alternatively, we can use launchctl bootout and launchctl bootstrap as the primary restart path, which can provide a more explicit and reliable way to restart the gateway.

// ...

// Call cleanStaleGatewayProcessesSync to kill the process group with SIGTERM
cleanStaleGatewayProcessesSync();

// Use launchctl bootout and launchctl bootstrap to restart the gateway
launchctlBootoutAndBootstrap();

// ...

function launchctlBootoutAndBootstrap() {
  // Call launchctl bootout gui/<uid>/ai.openclaw.gateway
  // Call launchctl bootstrap gui/<uid> <plist-path>
  // ...
}

Verification

To verify that the fix worked, we can test the restart mechanism by applying a config change that triggers a restart and checking that the gateway comes back up successfully. We can also monitor the gateway logs to ensure that the restart process is successful and that the gateway is functioning as expected.

Extra Tips

  • Make sure to test the restart mechanism thoroughly to ensure that it works reliably in different scenarios.
  • Consider implementing a retry mechanism for the bootstrap command in case it fails initially.
  • Monitor the gateway logs and system logs to detect any issues with the restart mechanism and make adjustments as needed.

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