From aaa9bd0f1c94fe8676dd025affe234e634bbf531 Mon Sep 17 00:00:00 2001 From: lbo728 Date: Sun, 22 Feb 2026 16:16:59 +0900 Subject: [PATCH] fix(config-reload): skip reload when config file is not found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a config file is written atomically (tmp → rename), chokidar can fire an 'unlink' event for the temporary removal of the destination file before the rename completes. runReload() would then call readSnapshot(), which returns { exists: false, valid: true, config: {} } — an empty config that looks valid — causing diffConfigPaths() to find many changes and triggering an unnecessary SIGUSR1 restart. The restarted gateway process then fails to find the config file (still in the middle of the write) and enters a crash loop with: 'Missing config. Run openclaw setup...' Fix: guard against exists=false before the existing valid=false check, so mid-write snapshots are silently skipped rather than treated as a config wipe. Fixes #23321 --- src/gateway/config-reload.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gateway/config-reload.ts b/src/gateway/config-reload.ts index 9be7f458a..8c3f7c231 100644 --- a/src/gateway/config-reload.ts +++ b/src/gateway/config-reload.ts @@ -297,6 +297,10 @@ export function startGatewayConfigReloader(opts: { } try { const snapshot = await opts.readSnapshot(); + if (!snapshot.exists) { + opts.log.warn("config reload skipped (config file not found; may be mid-write)"); + return; + } if (!snapshot.valid) { const issues = snapshot.issues.map((issue) => `${issue.path}: ${issue.message}`).join(", "); opts.log.warn(`config reload skipped (invalid config): ${issues}`);