Skip to content

fix: detect OpenClaw-managed launchd/systemd services in process respawn#27655

Merged
steipete merged 1 commit intoopenclaw:mainfrom
taw0002:fix/respawn-detect-supervised-env
Feb 26, 2026
Merged

fix: detect OpenClaw-managed launchd/systemd services in process respawn#27655
steipete merged 1 commit intoopenclaw:mainfrom
taw0002:fix/respawn-detect-supervised-env

Conversation

@taw0002
Copy link
Contributor

@taw0002 taw0002 commented Feb 26, 2026

Problem

restartGatewayProcessWithFreshPid() checks SUPERVISOR_HINT_ENV_VARS to decide whether to let the supervisor handle the restart (mode=supervised) or fork a detached child (mode=spawned). The existing list only included native launchd vars (LAUNCH_JOB_LABEL, LAUNCH_JOB_NAME) and systemd vars (INVOCATION_ID, SYSTEMD_EXEC_PID, JOURNAL_STREAM).

macOS launchd does NOT automatically inject LAUNCH_JOB_LABEL into the child environment. OpenClaw's own plist generator (buildServiceEnvironment in service-env.ts) sets OPENCLAW_LAUNCHD_LABEL instead.

So on stock macOS LaunchAgent installs:

  1. Config change triggers SIGUSR1
  2. isLikelySupervisedProcess() returns false (no native launchd env vars)
  3. Gateway forks a detached child (orphan)
  4. Original process exits
  5. launchd respawns → port taken by orphan → crash loop

Fix

Add OPENCLAW_LAUNCHD_LABEL, OPENCLAW_SYSTEMD_UNIT, and OPENCLAW_SERVICE_MARKER to SUPERVISOR_HINT_ENV_VARS. These are set by OpenClaw's own service environment builders for both launchd and systemd, making them the reliable supervised-mode signals.

Tests

  • 3 new test cases for OPENCLAW_LAUNCHD_LABEL, OPENCLAW_SYSTEMD_UNIT, and OPENCLAW_SERVICE_MARKER
  • All existing tests continue to pass (7 total)

Fixes #27605

restartGatewayProcessWithFreshPid() checks SUPERVISOR_HINT_ENV_VARS to
decide whether to let the supervisor handle the restart (mode=supervised)
or to fork a detached child (mode=spawned). The existing list only had
native launchd vars (LAUNCH_JOB_LABEL, LAUNCH_JOB_NAME) and systemd vars
(INVOCATION_ID, SYSTEMD_EXEC_PID, JOURNAL_STREAM).

macOS launchd does NOT automatically inject LAUNCH_JOB_LABEL into the
child environment. OpenClaw's own plist generator (buildServiceEnvironment
in service-env.ts) sets OPENCLAW_LAUNCHD_LABEL instead. So on stock macOS
LaunchAgent installs, isLikelySupervisedProcess() returned false, causing
the gateway to fork a detached child on SIGUSR1 restart. The original
process then exits, launchd sees its child died, respawns a new instance
which finds the orphan holding the port — infinite crash loop.

Fix: add OPENCLAW_LAUNCHD_LABEL, OPENCLAW_SYSTEMD_UNIT, and
OPENCLAW_SERVICE_MARKER to the supervisor hint list. These are set by
OpenClaw's own service environment builders for both launchd and systemd
and are the reliable supervised-mode signals.

Fixes openclaw#27605
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Fixes crash loop on macOS LaunchAgent installs by detecting OpenClaw-managed service environments.

  • Root cause: restartGatewayProcessWithFreshPid() only checked for native launchd/systemd env vars, but macOS launchd doesn't auto-inject LAUNCH_JOB_LABEL. OpenClaw's plist generator sets OPENCLAW_LAUNCHD_LABEL instead.
  • Fix: Added OPENCLAW_LAUNCHD_LABEL, OPENCLAW_SYSTEMD_UNIT, and OPENCLAW_SERVICE_MARKER to supervisor detection list
  • Impact: Prevents orphaned processes that block launchd from restarting the gateway after config changes
  • Testing: 3 new test cases verify each env var triggers supervised mode; all 7 tests pass

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Straightforward bug fix with clear problem/solution, comprehensive test coverage (3 new tests), verified integration with service-env.ts, no logical errors or security concerns, and simple focused changes
  • No files require special attention

Last reviewed commit: 38d0362

@steipete steipete merged commit 792ce7b into openclaw:main Feb 26, 2026
26 of 28 checks passed
@steipete
Copy link
Contributor

Landed via /landpr flow.

  • Gate: pnpm check && pnpm build && pnpm test -- src/infra/process-respawn.test.ts
  • Land commit: 229f8b3
  • Merge commit: 792ce7b

Thanks @taw0002!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gateway SIGUSR1 self-restart orphans process under launchd

2 participants