fix(gateway): recover config hot-reload after watcher errors#92027
Conversation
A chokidar watcher 'error' permanently disabled config hot-reload with a single warn. Re-create the watcher with bounded backoff (500ms/2s/5s, 3 retries); on exhausted budget escalate to log.error and flip a persistent hotReloadStatus to disabled. stop() clears any pending re-create timer.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff693011de
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| watcher = null; | ||
| void source?.close().catch(() => {}); |
There was a problem hiding this comment.
Await the failed watcher before completing stop
When stop() runs during the retry backoff, this fire-and-forget close is the only reference to the failed watcher because watcher has already been set to null; stop() therefore resolves without waiting for Chokidar to release its filesystem handles. Chokidar documents close() as asynchronous and requiring await, so shutdown can finish while the watcher is still active, and a retry can likewise create a replacement before the old watcher has closed. Track this close promise and await it from both recreation and stop().
Useful? React with 👍 / 👎.
|
Maintainer verification complete.
|
…w#92027) A chokidar watcher 'error' permanently disabled config hot-reload with a single warn. Re-create the watcher with bounded backoff (500ms/2s/5s, 3 retries); on exhausted budget escalate to log.error and flip a persistent hotReloadStatus to disabled. stop() clears any pending re-create timer.
…w#92027) A chokidar watcher 'error' permanently disabled config hot-reload with a single warn. Re-create the watcher with bounded backoff (500ms/2s/5s, 3 retries); on exhausted budget escalate to log.error and flip a persistent hotReloadStatus to disabled. stop() clears any pending re-create timer.
Summary
A chokidar watcher
errorpermanently disabled config hot-reload with only a single warn. Re-create the watcher with bounded backoff (500ms/2s/5s, 3 retries); on exhausted budget escalate tolog.errorand flip a persistenthotReloadStatustodisabled.stop()clears any pending re-create timer.CHANGELOG.mdedit (release-only perAGENTS.md).Why core (not ClawHub)
Core stability fix touching
src/gateway/config-reload.ts— perAGENTS.mdthese stay in core (security/core hardening, bundled regressions, missing core APIs), not optional skill bundles routed to ClawHub.Verification
node scripts/run-vitest.mjs run src/gateway/config-reload.test.ts=> 328 passedpnpm tsgo:core(tsconfig.core.json) => cleanoxfmt --check+oxlinton touched files => cleanReal behavior proof
node scripts/run-vitest.mjs run src/gateway/config-reload.test.ts{ stop }consumers unaffected (extrahotReloadStatusis structurally compatible).🤖 Generated with Claude Code