AntFleet

Disagreement · eba8958d-anthropic-1

MCP status poller can double-schedule timers and miss updates due to stale closure

solo Opus
repo df3ede3f·PR #2·reviewed 1 week ago

Opus finding

MCP status poller can double-schedule timers and miss updates due to stale closure

mediumconcurrencymedium
  • app/src/components/channels/mcp/McpServersTab.tsx:60-86
The effect depends on `statuses`, so every time fetchStatuses updates statuses, the effect re-runs: cleanup clears the existing timer and a new schedule() is started. That alone is wasteful (each poll triggers a full re-subscription) but more subtly, the recursive schedule() inside the setTimeout callback uses the same closure-captured fetchStatuses; combined with the effect cleanup firing every status change, there is a window where the in-flight setTimeout has already fired (`schedule()` re-queued) and then the cleanup runs and clears only the most recent ref — which is correct, but if statuses change while a poll is awaiting, the cleanup runs before the await resolves: the new effect schedules another timer, while the prior recursive call also calls schedule() upon resolution, briefly running two concurrent timers. Net result: variable poll cadence and occasional duplicated polling.

Recommendation

Use a setInterval guarded by a ref, or store the timer in ref and ensure recursive schedule checks a 'cancelled' flag set by cleanup. Alternatively, depend only on `hasConnected` (derived) instead of the whole `statuses` array to avoid re-subscribing on every poll.

Other reviewer

The other reviewer flagged nothing in this file/line range.

Why this didn't post

This finding didn't meet AntFleet's unanimous agreement threshold. Both frontier models review every PR independently; only findings they both flag with the same severity and category are posted to the PR. This one fell through.

read the methodology →