fix(daemon): prevent systemd restart storm on config validation failure

Exit gateway configuration failures with EX_CONFIG and teach generated systemd units not to restart on that exit status.\n\nCo-authored-by: neo1027144-creator <neo1027144-creator@users.noreply.github.com>
This commit is contained in:
neo1027144
2026-04-10 23:23:46 +08:00
committed by GitHub
parent fc5a231e95
commit 2cf9ed782d
5 changed files with 18 additions and 4 deletions

View File

@@ -247,7 +247,7 @@ describe("gateway run option collisions", () => {
},
};
await expect(runGatewayCli(["gateway", "run"])).rejects.toThrow("__exit__:1");
await expect(runGatewayCli(["gateway", "run"])).rejects.toThrow("__exit__:78");
expect(runtimeErrors).toContain(
"Gateway start blocked: existing config is missing gateway.mode. Treat this as suspicious or clobbered config. Re-run `openclaw onboard --mode local` or `openclaw setup`, set gateway.mode=local manually, or pass --allow-unconfigured.",

View File

@@ -97,6 +97,13 @@ const GATEWAY_RUN_BOOLEAN_KEYS = [
const SUPERVISED_GATEWAY_LOCK_RETRY_MS = 5000;
/**
* EX_CONFIG (78) from sysexits.h — used for configuration errors so systemd
* (via RestartPreventExitStatus=78) stops restarting instead of entering a
* restart storm that can render low-resource hosts unresponsive.
*/
const EXIT_CONFIG_ERROR = 78;
const GATEWAY_AUTH_MODES: readonly GatewayAuthMode[] = [
"none",
"token",
@@ -429,7 +436,7 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
for (const error of guardErrors) {
defaultRuntime.error(error);
}
defaultRuntime.exit(1);
defaultRuntime.exit(EXIT_CONFIG_ERROR);
return;
}
const miskeys = extractGatewayMiskeys(snapshot?.parsed);
@@ -487,7 +494,7 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
.filter(Boolean)
.join("\n"),
);
defaultRuntime.exit(1);
defaultRuntime.exit(EXIT_CONFIG_ERROR);
return;
}
if (resolvedAuthMode === "none") {
@@ -517,7 +524,7 @@ async function runGatewayCommand(opts: GatewayRunOpts) {
.filter(Boolean)
.join("\n"),
);
defaultRuntime.exit(1);
defaultRuntime.exit(EXIT_CONFIG_ERROR);
return;
}
const tailscaleOverride =