Skip to content

macOS: retry stale launchd bootstrap#81728

Closed
BunsDev wants to merge 1 commit into
mainfrom
meow/macos-launchd-bootstrap-retry
Closed

macOS: retry stale launchd bootstrap#81728
BunsDev wants to merge 1 commit into
mainfrom
meow/macos-launchd-bootstrap-retry

Conversation

@BunsDev

@BunsDev BunsDev commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Retry macOS LaunchAgent bootstrap once after an already-registered launchd job is booted out.
  • Keep headless/sudo GUI-domain failures on the existing actionable guidance path.
  • Report the retry failure detail when recovery reaches a different launchctl error.

Refs #46153 and #48476.

Verification

Behavior addressed: openclaw gateway install/start/restart can recover a stale already-registered LaunchAgent without adding a legacy launchctl load -w fallback.
Real environment tested: local Codex worktree on macOS with targeted unit proof; no live launchd smoke yet.
Exact steps or command run after this patch: PATH=/Users/buns/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin:$PATH node scripts/run-vitest.mjs src/daemon/launchd.test.ts; PATH=/Users/buns/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin:$PATH pnpm exec oxfmt --check --threads=1 src/daemon/launchd.ts src/daemon/launchd.test.ts; git diff --check.
Evidence after fix: targeted Vitest passed 1 file, 52 tests passed; oxfmt check passed; git diff whitespace check passed.
Observed result after fix: already-registered bootstrap errors trigger bootout gui/<uid>/<label> and one bootstrap retry; retry GUI-domain failures keep the logged-in-session guidance path.
What was not tested: live macOS LaunchAgent reinstall/bootstrap smoke and broad Testbox pnpm check:changed are still pending for the full four-slice queue.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S maintainer Maintainer-authored PR labels May 14, 2026
@clawsweeper

clawsweeper Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Summary
The PR adds a one-time bootout and bootstrap retry for macOS LaunchAgent already-registered bootstrap failures, updates launchd tests, and adds a changelog entry.

Reproducibility: yes. source-backed: current main throws after an already-registered bootstrap failure, while the PR adds the missing bootout-and-retry branch and focused coverage. I did not live-reproduce the failure with macOS launchd.

Real behavior proof
Not applicable: Maintainer/member PR, so the external contributor proof gate does not apply; the remaining live macOS smoke is a maintainer validation gap before landing.

Next step before merge
Protected maintainer-labeled PR with no blocking review finding, but it needs normal maintainer handling and real macOS launchd smoke before landing.

Security
Cleared: No concrete security or supply-chain regression found; the diff changes existing launchd control flow and tests without adding dependencies, workflow changes, secret handling, or legacy root-scoped load fallback.

Review details

Best possible solution:

Land the retry-only launchd recovery after maintainer review and real macOS smoke, leaving headless/sudo support on the documented GUI-session guidance unless a separate LaunchDaemon product decision is made.

Do we have a high-confidence way to reproduce the issue?

Yes, source-backed: current main throws after an already-registered bootstrap failure, while the PR adds the missing bootout-and-retry branch and focused coverage. I did not live-reproduce the failure with macOS launchd.

Is this the best way to solve the issue?

Yes. The PR is the narrow maintainable fix for stale already-registered bootstrap recovery because it retries only the per-user LaunchAgent path and avoids the legacy launchctl load -w fallback rejected in the related review.

What I checked:

  • protected_member_pr: The provided GitHub context shows author association MEMBER and labels include maintainer, so this cleanup workflow must keep the PR open for explicit maintainer handling. (2d81aa7e1086)
  • current_main_bootstrap_path: Current main enables the LaunchAgent service target, runs launchctl bootstrap, maps unsupported GUI-domain errors to the existing logged-in-session guidance, and otherwise throws without a retry for already-registered bootstrap failures. (src/daemon/launchd.ts:297, 11017c93cf14)
  • pr_retry_patch: The PR patch adds isAlreadyBootstrappedDetail, bootouts the per-user service target on already-registered bootstrap errors, retries bootstrap once, and preserves GUI-session guidance for retry failures without adding the legacy load fallback. (src/daemon/launchd.ts:315, 2d81aa7e1086)
  • pr_regression_coverage: The PR adds focused tests for successful retry after an already exists in domain bootstrap error and for reporting the retry's different bootstrap failure detail. (src/daemon/launchd.test.ts:520, 2d81aa7e1086)
  • related_review_context: The related review on fix(daemon): resilient launchctl bootstrap with retry and load fallback #48476 identified the legacy launchctl load -w fallback as the risky part and named a narrow duplicate-bootstrap retry as the safer direction; this PR implements that narrower slice. (0486b9f0c3c4)
  • path_history: Recent GitHub path history for launchd code shows repeated macOS LaunchAgent lifecycle work from steipete and vincentkoc, plus adjacent plist and update-restart work from BunsDev and bryanpearson. (src/daemon/launchd.ts, 1f88cb2ce5dd)

Likely related people:

  • steipete: Recent merged macOS LaunchAgent lifecycle commits changed src/daemon/launchd.ts, tests, and gateway lifecycle docs near this retry path. (role: recent area contributor; confidence: high; commits: 1f88cb2ce5dd, 1ace6a0d6a0d, a6141a5a4196; files: src/daemon/launchd.ts, src/daemon/launchd.test.ts, docs/gateway/index.md)
  • vincentkoc: Recent merged work reconciled macOS LaunchAgent supervision state across launchd, daemon CLI, doctor flow, and tests. (role: recent adjacent contributor; confidence: high; commits: 60d4d5e1fa05; files: src/daemon/launchd.ts, src/daemon/launchd.test.ts, src/daemon/launchd.integration.e2e.test.ts)
  • BunsDev: Besides authoring this PR, prior merged history shows macOS gateway update/restart lifecycle work touching launchd-related tests and plist policy. (role: recent adjacent contributor; confidence: medium; commits: fa79e9754ecc; files: src/daemon/launchd.test.ts, src/daemon/launchd-plist.ts, src/cli/update-cli/update-command.ts)
  • bryanpearson: Recent merged plist policy work set ProcessType=Interactive, which is relevant launchd context for keeping headless/sudo paths on guidance instead of legacy load fallback. (role: adjacent plist contributor; confidence: medium; commits: a2b8f2aef083; files: src/daemon/launchd-plist.ts, src/daemon/launchd.test.ts)

Remaining risk / open question:

  • No live macOS LaunchAgent reinstall/bootstrap smoke is in the PR body yet.
  • I did not run tests in this read-only checkout; validation is based on source inspection and the PR-provided targeted unit/format proof.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 11017c93cf14.

@BunsDev

BunsDev commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

Broad verification update:

  • Testbox pnpm check:changed passed for meow/macos-launchd-bootstrap-retry.
  • Testbox: tbx_01krjqgj1arq9w4gr39kgvsph5
  • Command: (git fetch/unshallow origin main for merge-base) && pnpm check:changed
  • Result: exit 0.

@BunsDev

BunsDev commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

Closing this as superseded. The launchd startup work this was tied to has already landed through the later path, and the referenced follow-up context is no longer current. Rather than keep an old dirty branch open, we can open a fresh targeted PR if a new bootstrap retry bug appears on current main.

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

Labels

gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant