fix(gateway): skip config.patch restart for hot-reloadable changes#46397
fix(gateway): skip config.patch restart for hot-reloadable changes#46397LarytheLord wants to merge 1 commit into
Conversation
Greptile SummaryThis PR fixes a genuine bug where Key observations:
Confidence Score: 4/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/gateway/config-reload.ts
Line: 81-83
Comment:
**`off` mode restarts all non-empty patches, including no-op paths**
When `mode === "off"` the function returns `true` for *any* non-empty `changedPaths` — including paths classified as `kind: "none"` (e.g. `meta.version`, `identity`, `logging`). The file-watcher path in `applySnapshot` handles `off` mode by doing nothing at all, so this "always restart in `off` mode" behaviour is the only way to guarantee changes written by `config.patch` take effect in-process. That reasoning is sound, but it means a user who sets `mode = "off"` to suppress auto-restarts will still see a restart on *every* explicit `config.patch` call, even for purely cosmetic/no-op fields.
If that edge case matters, you could mirror the `hot`/`hybrid` path and short-circuit when `buildGatewayReloadPlan(changedPaths).restartGateway === false` before the mode guard. For now the backward-compatible behaviour is preserved, so this is just something to be aware of.
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: f5282c8 |
| if (settings.mode === "off" || settings.mode === "restart") { | ||
| return true; | ||
| } |
There was a problem hiding this comment.
off mode restarts all non-empty patches, including no-op paths
When mode === "off" the function returns true for any non-empty changedPaths — including paths classified as kind: "none" (e.g. meta.version, identity, logging). The file-watcher path in applySnapshot handles off mode by doing nothing at all, so this "always restart in off mode" behaviour is the only way to guarantee changes written by config.patch take effect in-process. That reasoning is sound, but it means a user who sets mode = "off" to suppress auto-restarts will still see a restart on every explicit config.patch call, even for purely cosmetic/no-op fields.
If that edge case matters, you could mirror the hot/hybrid path and short-circuit when buildGatewayReloadPlan(changedPaths).restartGateway === false before the mode guard. For now the backward-compatible behaviour is preserved, so this is just something to be aware of.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/gateway/config-reload.ts
Line: 81-83
Comment:
**`off` mode restarts all non-empty patches, including no-op paths**
When `mode === "off"` the function returns `true` for *any* non-empty `changedPaths` — including paths classified as `kind: "none"` (e.g. `meta.version`, `identity`, `logging`). The file-watcher path in `applySnapshot` handles `off` mode by doing nothing at all, so this "always restart in `off` mode" behaviour is the only way to guarantee changes written by `config.patch` take effect in-process. That reasoning is sound, but it means a user who sets `mode = "off"` to suppress auto-restarts will still see a restart on *every* explicit `config.patch` call, even for purely cosmetic/no-op fields.
If that edge case matters, you could mirror the `hot`/`hybrid` path and short-circuit when `buildGatewayReloadPlan(changedPaths).restartGateway === false` before the mode guard. For now the backward-compatible behaviour is preserved, so this is just something to be aware of.
How can I resolve this? If you propose a fix, please make it concise.f5282c8 to
cb00010
Compare
|
Closing this as implemented after Codex review. Current What I checked:
So I’m closing this as already implemented rather than keeping a duplicate issue open. Review notes: reviewed against 56fe2aab9c87; fix evidence: release v2026.4.22, commit 00bd2cf7a376. |
Summary
config.patchalways queuedscheduleGatewaySigusr1Restart()after writing the config, even when the changed paths were already classified as hot-reloadable or no-op by the gateway reload planner.config.patchnow reuses the existing reload planner plus the patchedgateway.reload.modeto decide whether a restart is actually needed; when it is not, the handler skips both restart-sentinel creation and SIGUSR1 scheduling.config.applyis unchanged, and explicitconfig.patchcalls still restart for restart-required paths (and when reload mode isofforrestart).Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
config.patchno longer forces a gateway restart for hot-reloadable / no-op config changes when the patched reload mode allows in-process reloads.restart: nullandsentinel: null.config.patchhot-reloads when possible.Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) NoYes, explain risk + mitigation:Repro + Verification
Environment
gateway.reload.mode="restart", patched to"hybrid"for the hot-reload regression caseSteps
gateway.reload.modeisrestart.config.patchwith a browser-profile change plusgateway.reload.mode: "hybrid".Expected
config.patchwrites should persist and return without scheduling a restart.Actual
config.patchalways queued restart+sentry work even for hot-reloadable changes.Evidence
src/gateway/config-reload.test.tsandsrc/gateway/server-methods/config.restart.test.ts.pnpm exec vitest run src/gateway/config-reload.test.ts src/gateway/server-methods/config.restart.test.ts src/agents/system-prompt.test.ts src/agents/openclaw-gateway-tool.test.tspnpm exec oxfmt --check src/agents/system-prompt.ts src/agents/tools/gateway-tool.ts src/gateway/config-reload.test.ts src/gateway/config-reload.ts src/gateway/server-methods/config.ts src/gateway/server-methods/config.restart.test.tspnpm tsgopnpm buildHuman Verification (required)
What you personally verified (not just CI), and how:
gateway.reload.modeis used for the restart decisionoff/restartmodes still keep explicitconfig.patchrestart behaviorReview Conversations
If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.
Compatibility / Migration
Yes/No) YesYes/No) NoYes/No) NoFailure Recovery (if this breaks)
config.patchwrite.src/gateway/config-reload.tssrc/gateway/server-methods/config.tsconfig.patchchanges unexpectedly returningrestartagainRisks and Mitigations