← Back to PRs

#12786: fix: drop heartbeat runs that arrive while another run is active

by mcaxtr open 2026-02-09 17:38 View on GitHub →
size: S trusted-contributor experienced-contributor
## Summary Fixes #8063 When a heartbeat run arrives while another agent run is already active for the same session, it was being enqueued as a followup. When the followup queue later drained, the stale heartbeat produced a duplicate agent run — sending extra response branches to the user. This change adds an early-return guard in `runReplyAgent` that silently drops heartbeat runs when `isActive` is true, before they reach the enqueue path. The next heartbeat interval will independently re-check the session. - Non-heartbeat runs are unaffected — they continue to enqueue normally - The followup drain mechanism remains fully intact for legitimate queued messages - Heartbeat runs that arrive when no other run is active execute normally ## Test plan - [x] New test: heartbeat run is dropped (returns `undefined`, no enqueue) when `isActive: true` - [x] New test: non-heartbeat run still enqueues when `isActive: true` - [x] New test: heartbeat run executes normally when `isActive: false` - [x] All 3 new tests fail before the fix, pass after (TDD) - [x] Existing agent-runner test suites pass (13 test files) - [x] Existing heartbeat-runner test suites pass (43 tests) - [x] `pnpm build && pnpm check` pass <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This change adds a guard in `src/auto-reply/reply/agent-runner.ts` to silently drop heartbeat-triggered runs when another run is already active for the same session, preventing stale heartbeat followups from being enqueued and later producing duplicate agent runs/extra response branches (fix for #8063). It also adds a focused vitest suite that asserts: (1) heartbeat+active returns `undefined` and does not enqueue, (2) non-heartbeat+active still enqueues, and (3) heartbeat+inactive proceeds to execute normally. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk. - The change is narrowly scoped (an early-return guard for a specific heartbeat+active condition) and is covered by new targeted tests that validate both the new behavior and non-regression for non-heartbeat runs. The previously reported run-completion bookkeeping gap on the early-return path is addressed in the current diff via explicit `typing.markRunComplete()` calls. - No files require special attention <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs