← Back to PRs

#19387: Fix #19302: Filter isError payloads before heartbeat selection

by cedillarack open 2026-02-17 18:52 View on GitHub →
channel: whatsapp-web size: S
## Problem Tool error summaries (e.g., `⚠️ 🛠️ Exec: ...`) are delivered to channels even when agent responds with `HEARTBEAT_OK`. ## Root Cause `resolveHeartbeatReplyPayload` iterates backwards and picks the error payload over `HEARTBEAT_OK` responses. ## Solution Filter out error payloads (where `isError === true`) before passing to `resolveHeartbeatReplyPayload`. ## Files Modified - `src/infra/heartbeat-runner.ts` (line 661) - `src/web/auto-reply/heartbeat-runner.ts` (line 176) - `src/auto-reply/heartbeat-reply-payload.test.ts` (new test file) ## Test Coverage Comprehensive test suite including: - Basic payload resolution behavior - Error payload filtering - Mixed payload arrays - Edge cases All tests passing ✅ <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR fixes issue #19302, where tool error summary payloads (with `isError: true`) were being selected as the heartbeat reply instead of the `HEARTBEAT_OK` response. The fix filters `isError` payloads from the array before it is passed to `resolveHeartbeatReplyPayload` in both `src/infra/heartbeat-runner.ts` and `src/web/auto-reply/heartbeat-runner.ts`. **Key changes:** - Both heartbeat runners now pre-filter `isError` payloads from array results before selecting the reply payload. - A new test file `src/auto-reply/heartbeat-reply-payload.test.ts` adds coverage for `resolveHeartbeatReplyPayload`. **Issues found:** - The `BUG #19302` tests in the new test file perform filtering *within the test body* (calling `.filter((p) => !p.isError)` manually) rather than going through the production runners. This means the tests don't actually verify the fix in either heartbeat runner — a caller that forgets to pre-filter would not be caught by these tests. The tests would pass even if the filtering was removed from the production code. - The fix is intentionally scoped to arrays: a single non-array `isError` payload is not filtered. This gap is documented in the test (line 73–81) but not addressed or discussed in the PR description. - The inline filtering expression is duplicated across two files. If a third caller is ever added, the same pattern must be manually applied there too. <h3>Confidence Score: 3/5</h3> - The core fix is correct and addresses the reported bug, but the test suite validates the filtering in isolation rather than through the production code paths, reducing confidence in regression coverage. - The production fix (filtering `isError` payloads in both heartbeat runners) is correct and solves the reported problem. However, the new tests test the filtering logic inline in the test body rather than exercising the actual runner code, meaning they wouldn't catch a regression if the filter was removed from the runners. Additionally, the fix is duplicated across two files rather than being centralized, creating a maintenance risk for future callers. - src/auto-reply/heartbeat-reply-payload.test.ts — the BUG #19302 test suite does not cover the actual fix in the heartbeat runners <sub>Last reviewed commit: a276b95</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs