config.patch unconditionally schedules SIGUSR1 restart, ignoring hot-reload capability
Version: OpenClaw 2026.3.8 (3caab92)
Platform: macOS (LaunchAgent), Node 22
Summary
The config.patch WS API handler unconditionally calls scheduleGatewaySigusr1Restart() after writing the config file, even when the changed paths are fully hot-reloadable. This causes unnecessary gateway restarts (and brief downtime) for config changes that the file watcher's reload planner would handle in-process.
Expected Behavior
When config.patch modifies only hot-reloadable paths (e.g., channel group settings, heartbeat config, cron config), the gateway should apply the change via hot reload without a full process restart — the same way the file watcher handles it when the config file is edited directly.
Actual Behavior
config.patch writes the config file via writeConfigFile()
- The file watcher detects the change and successfully hot-reloads it (logged as
config hot reload applied or config change applied (dynamic reads: ...))
- ~2 seconds later,
scheduleGatewaySigusr1Restart() fires unconditionally
- On macOS with LaunchAgent, SIGUSR1 triggers
launchctl kickstart -k → SIGTERM → full process restart
The hot reload at step 2 already applied the change. The restart at step 3-4 is redundant and kills the gateway.
Reproduction
- Run OpenClaw as a LaunchAgent on macOS
- Have an agent use the
config.patch tool to change a hot-reloadable setting (e.g., a Telegram group's requireMention flag)
- Observe logs:
config change detected; evaluating reload (...) → hot reload applied ✅
- ~2-3 seconds later:
signal SIGTERM received → received SIGTERM; shutting down 💀
Root Cause
In gateway-cli (around the config.patch handler), after writeConfigFile():
const restart = scheduleGatewaySigusr1Restart({
delayMs: restartDelayMs,
reason: "config.patch",
// ...
});
There is no check against buildGatewayReloadPlan() to determine if the changed paths actually require a restart. The file watcher's reload path does have this classification logic and correctly skips restarts for hot-reloadable changes.
Suggested Fix
Before scheduling the restart in config.patch, run the same reload plan classification that the file watcher uses:
const plan = buildGatewayReloadPlan(changedPaths);
if (!plan.restartGateway) {
// Let the file watcher handle it via hot reload
// Skip scheduleGatewaySigusr1Restart()
} else {
scheduleGatewaySigusr1Restart({ ... });
}
Alternatively, config.patch could skip calling scheduleGatewaySigusr1Restart() entirely and rely on the file watcher (since it already writes the file), though that might miss changes that genuinely require a restart on platforms without file watching.
Impact
- Every agent-initiated config change causes a full gateway restart (~5-10s downtime)
- On macOS LaunchAgent, if
launchctl bootstrap fails after bootout, the gateway stays dead until manual intervention (openclaw doctor --fix)
- Makes agent config automation unreliable
config.patchunconditionally schedules SIGUSR1 restart, ignoring hot-reload capabilityVersion: OpenClaw 2026.3.8 (3caab92)
Platform: macOS (LaunchAgent), Node 22
Summary
The
config.patchWS API handler unconditionally callsscheduleGatewaySigusr1Restart()after writing the config file, even when the changed paths are fully hot-reloadable. This causes unnecessary gateway restarts (and brief downtime) for config changes that the file watcher's reload planner would handle in-process.Expected Behavior
When
config.patchmodifies only hot-reloadable paths (e.g., channel group settings, heartbeat config, cron config), the gateway should apply the change via hot reload without a full process restart — the same way the file watcher handles it when the config file is edited directly.Actual Behavior
config.patchwrites the config file viawriteConfigFile()config hot reload appliedorconfig change applied (dynamic reads: ...))scheduleGatewaySigusr1Restart()fires unconditionallylaunchctl kickstart -k→ SIGTERM → full process restartThe hot reload at step 2 already applied the change. The restart at step 3-4 is redundant and kills the gateway.
Reproduction
config.patchtool to change a hot-reloadable setting (e.g., a Telegram group'srequireMentionflag)config change detected; evaluating reload (...)→ hot reload applied ✅signal SIGTERM received→received SIGTERM; shutting down💀Root Cause
In
gateway-cli(around theconfig.patchhandler), afterwriteConfigFile():There is no check against
buildGatewayReloadPlan()to determine if the changed paths actually require a restart. The file watcher's reload path does have this classification logic and correctly skips restarts for hot-reloadable changes.Suggested Fix
Before scheduling the restart in
config.patch, run the same reload plan classification that the file watcher uses:Alternatively,
config.patchcould skip callingscheduleGatewaySigusr1Restart()entirely and rely on the file watcher (since it already writes the file), though that might miss changes that genuinely require a restart on platforms without file watching.Impact
launchctl bootstrapfails afterbootout, the gateway stays dead until manual intervention (openclaw doctor --fix)