codex - 💡(How to fix) Fix fs/watch debounce only applies to the first event batch [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

I found a debounce bug in the app-server fs/watch notification path. The local debounce wrapper in app-server/src/fs_watch.rs stores the next deadline in next_allowance and initializes it only once. After the first event batch is emitted, later batches reuse that stale Instant, so subsequent filesystem changes can be emitted immediately instead of being debounced.

The upstream repository currently only allows collaborators to open pull requests, so I pushed a fix to my fork instead:

Root Cause

Before the fix, step 6 can fail because the stale deadline is already in the past.

Fix Action

Fixed

Code Example

just fmt
PATH="$HOME/.cargo/bin:$PATH" just test -p codex-file-watcher
PATH="$HOME/.cargo/bin:$PATH" just test -p codex-app-server fs_watch
RAW_BUFFERClick to expand / collapse

Summary

I found a debounce bug in the app-server fs/watch notification path. The local debounce wrapper in app-server/src/fs_watch.rs stores the next deadline in next_allowance and initializes it only once. After the first event batch is emitted, later batches reuse that stale Instant, so subsequent filesystem changes can be emitted immediately instead of being debounced.

The upstream repository currently only allows collaborators to open pull requests, so I pushed a fix to my fork instead:

Impact

The first burst of file watcher events is coalesced correctly, but later bursts may bypass the intended debounce window. In the app-server path this affects fs/changed notifications, where the debounce interval is currently 200ms.

In practical terms, after the first notification burst, clients can receive noisier and less stable fs/changed notifications than intended.

Fix in the fork

The forked branch:

  • moves the debouncing wrapper into codex-file-watcher as DebouncedWatchReceiver
  • resets the debounce deadline for each event batch
  • uses deterministic path ordering via BTreeSet
  • flushes pending paths if the watcher channel closes during a debounce window
  • updates app-server fs/watch to use the shared debounce receiver

Regression coverage

I added a unit test with a 50ms debounce interval that verifies the second event batch is still debounced:

  1. send a
  2. wait 25ms
  3. send b
  4. receive one batch [a, b]
  5. send c
  6. assert recv() does not return within 25ms
  7. send d
  8. receive one batch [c, d]

Before the fix, step 6 can fail because the stale deadline is already in the past.

I also added coverage for flushing pending debounced paths when the sender closes.

Validation

Ran locally:

just fmt
PATH="$HOME/.cargo/bin:$PATH" just test -p codex-file-watcher
PATH="$HOME/.cargo/bin:$PATH" just test -p codex-app-server fs_watch

Results:

  • codex-file-watcher: 21 tests passed
  • codex-app-server fs_watch: 8 tests passed, 777 skipped
  • the bench-smoke step run by just test also passed

One unrelated existing warning appeared from codex-exec-server/src/client.rs about an unused variable.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix fs/watch debounce only applies to the first event batch [1 pull requests]