From db35f300051a6a8994ef6f6896f0cc059a23ed62 Mon Sep 17 00:00:00 2001 From: HCL Date: Wed, 25 Mar 2026 08:04:32 +0800 Subject: [PATCH] fix: validate config before restart + derive loaded from real state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Codex P1 + Greptile P2: - Move config validation before the restart attempt so invalid config is caught in the stop→start path (not just the already-loaded path) - Derive service.loaded from actual isLoaded() after restart instead of hardcoded true Co-Authored-By: Claude Opus 4.6 Signed-off-by: HCL --- src/cli/daemon-cli/lifecycle-core.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/cli/daemon-cli/lifecycle-core.ts b/src/cli/daemon-cli/lifecycle-core.ts index 83264e99932..10cfc0240c8 100644 --- a/src/cli/daemon-cli/lifecycle-core.ts +++ b/src/cli/daemon-cli/lifecycle-core.ts @@ -208,6 +208,17 @@ export async function runServiceStart(params: { if (loaded === null) { return; } + // Pre-flight config validation (#35862) — run for both loaded and not-loaded + // to prevent launching from invalid config in any start path. + { + const configError = await getConfigValidationError(); + if (configError) { + fail( + `${params.serviceNoun} aborted: config is invalid.\n${configError}\nFix the config and retry, or run "openclaw doctor" to repair.`, + ); + return; + } + } if (!loaded) { // Service was stopped (e.g. `gateway stop` booted out the LaunchAgent). // Attempt a restart, which handles re-bootstrapping the service. Without @@ -215,11 +226,12 @@ export async function runServiceStart(params: { try { const restartResult = await params.service.restart({ env: process.env, stdout }); const restartStatus = describeGatewayServiceRestart(params.serviceNoun, restartResult); + const postLoaded = await params.service.isLoaded({ env: process.env }).catch(() => true); emit({ ok: true, result: restartStatus.daemonActionResult, message: restartStatus.message, - service: buildDaemonServiceSnapshot(params.service, true), + service: buildDaemonServiceSnapshot(params.service, postLoaded), }); if (!json) { defaultRuntime.log(restartStatus.message); @@ -239,16 +251,6 @@ export async function runServiceStart(params: { return; } } - // Pre-flight config validation (#35862) - { - const configError = await getConfigValidationError(); - if (configError) { - fail( - `${params.serviceNoun} aborted: config is invalid.\n${configError}\nFix the config and retry, or run "openclaw doctor" to repair.`, - ); - return; - } - } try { const restartResult = await params.service.restart({ env: process.env, stdout });