← Back to PRs

#11280: fix(gateway): add meta prefix to reload rules to prevent double SIGUSR1

by cheenu1092-oss open 2026-02-07 17:07 View on GitHub →
gateway stale
## Summary Adds `{ prefix: "meta", kind: "none" }` to the `BASE_RELOAD_RULES` array to prevent `meta.lastTouchedAt` config changes from triggering unnecessary gateway restarts. ## Problem When `config.patch` writes the configuration file: 1. It updates `meta.lastTouchedAt` (`src/config/io.ts:143`) 2. It schedules a SIGUSR1 restart But the file watcher also detects this change, and since `meta.*` paths have no reload rule, they fall through to the default `restartGateway = true` path — triggering a **second SIGUSR1** ~1.4 seconds later. ### Evidence from logs: ``` 04:58:49.469Z config change requires gateway restart (meta.lastTouchedAt) 04:58:49.471Z signal SIGUSR1 received 04:58:49.520Z cron: started 04:58:50.946Z signal SIGUSR1 received ← SECOND SIGUSR1 04:58:52.498Z cron: started ``` ## Root Cause In `src/gateway/config-reload.ts`, the `BASE_RELOAD_RULES` array lacks a rule for the `meta` prefix. When `buildGatewayReloadPlan()` processes `meta.lastTouchedAt`, it finds no matching rule and defaults to `restartGateway = true` (line 226). ## Fix Add the `meta` prefix to the no-op rules: ```diff const BASE_RELOAD_RULES: ReloadRule[] = [ { prefix: "gateway.remote", kind: "none" }, { prefix: "gateway.reload", kind: "none" }, + { prefix: "meta", kind: "none" }, { prefix: "hooks.gmail", kind: "hot", actions: ["restart-gmail-watcher"] }, ``` The `meta` section contains bookkeeping metadata (`lastTouchedAt`, `version`) that should never trigger a gateway restart. ## Impact This double-restart: - Causes unnecessary service disruption - Creates race conditions during rapid restart cycles - Exacerbates timer GC issues during idle periods (the restart flurry can cause cron timers to be garbage collected before the server is fully listening) ## Testing All existing tests pass: ``` ✓ src/gateway/config-reload.test.ts (8 tests) ✓ src/cron/ (86 tests) ``` ## Related Issues Fixes: #11279 Fixes: #5533 Related: - #11013 — Cron scheduler stalls after SIGUSR1 restart - #10849 — Cron scheduler timer never fires - #9084 — Heartbeat timer stops after macOS sleep/wake <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR updates the gateway config reload rules so that config changes under the `meta.*` prefix are treated as no-ops. Concretely, it adds `{ prefix: "meta", kind: "none" }` to `BASE_RELOAD_RULES` in `src/gateway/config-reload.ts`, which aligns with the current config schema where `meta.lastTouchedVersion` / `meta.lastTouchedAt` are auto-stamped bookkeeping fields when OpenClaw writes the config. Without this rule, `buildGatewayReloadPlan()` treats unknown config paths as requiring a full gateway restart, which can lead to a second SIGUSR1 restart when the file watcher observes the `meta.lastTouchedAt` write. Change scope is limited to reload planning logic; no other behavior is modified. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk. - The change is a single additional reload rule and matches existing config schema semantics: `meta` is strictly defined as optional bookkeeping fields that are auto-written by OpenClaw. Adding it to the no-op prefix list prevents unnecessary restarts without impacting operational config reload decisions. - No files require special attention <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs