mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-27 09:21:35 +07:00
fix(daemon): bootstrap stopped service on gateway start
After `gateway stop` (which runs `launchctl bootout`), `gateway start` checks `isLoaded` → false → prints "not loaded" hints and exits. The service is never re-bootstrapped, so `start` cannot recover from `stop` — only `gateway install` works. Root cause: src/cli/daemon-cli/lifecycle-core.ts:208-217 — runServiceStart calls handleServiceNotLoaded which only prints hints, never attempts service.restart() (which already handles bootstrap via bootstrapLaunchAgentOrThrow at launchd.ts:598). Fix: when service is not loaded, attempt service.restart() first (which handles re-bootstrapping on all platforms). If restart fails (e.g. plist was deleted, not just booted out), fall back to the existing hints. The restart path is already proven: restartLaunchAgent (launchd.ts:556) handles "not loaded" via bootstrapLaunchAgentOrThrow. This fix routes the start command through the same recovery path. Closes #53878 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: HCL <chenglunhu@gmail.com>
This commit is contained in:
@@ -209,15 +209,35 @@ export async function runServiceStart(params: {
|
||||
return;
|
||||
}
|
||||
if (!loaded) {
|
||||
await handleServiceNotLoaded({
|
||||
serviceNoun: params.serviceNoun,
|
||||
service: params.service,
|
||||
loaded,
|
||||
renderStartHints: params.renderStartHints,
|
||||
json,
|
||||
emit,
|
||||
});
|
||||
return;
|
||||
// Service was stopped (e.g. `gateway stop` booted out the LaunchAgent).
|
||||
// Attempt a restart, which handles re-bootstrapping the service. Without
|
||||
// this, `start` after `stop` just prints hints and does nothing (#53878).
|
||||
try {
|
||||
const restartResult = await params.service.restart({ env: process.env, stdout });
|
||||
const restartStatus = describeGatewayServiceRestart(params.serviceNoun, restartResult);
|
||||
emit({
|
||||
ok: true,
|
||||
result: restartStatus.daemonActionResult,
|
||||
message: restartStatus.message,
|
||||
service: buildDaemonServiceSnapshot(params.service, true),
|
||||
});
|
||||
if (!json) {
|
||||
defaultRuntime.log(restartStatus.message);
|
||||
}
|
||||
return;
|
||||
} catch {
|
||||
// Bootstrap failed (e.g. plist was deleted, not just booted out).
|
||||
// Fall through to the not-loaded hints.
|
||||
await handleServiceNotLoaded({
|
||||
serviceNoun: params.serviceNoun,
|
||||
service: params.service,
|
||||
loaded,
|
||||
renderStartHints: params.renderStartHints,
|
||||
json,
|
||||
emit,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Pre-flight config validation (#35862)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user