#21454: fix(cron): skip isError payloads when picking summary/delivery content
size: S
Cluster:
Error Payload Filtering
## Summary
Fixes #21453.
`buildEmbeddedRunPayloads` appends `isError: true` warnings as the last payload (tool errors, rate limit warnings, billing errors). Three functions in `helpers.ts` iterate last-to-first and pick the error over real agent output, causing cron summaries and deliveries to show error messages instead of actual responses.
All three functions now use two-pass selection:
1. First pass: skip `isError: true` entries, pick last non-empty real content
2. Second pass (fallback): include error entries, so error-only runs still get a summary
### Changes
- `pickSummaryFromPayloads` — widened type to accept `isError?: boolean`, two-pass logic
- `pickLastNonEmptyTextFromPayloads` — same pattern
- `pickLastDeliverablePayload` — added `isError` to `DeliveryPayload` type, same pattern
### Edge cases
- Mixed payloads (real text + error) → picks real text
- Error-only payloads → returns error (not undefined)
- No payloads → unchanged (returns undefined)
- `isError: undefined` → treated as non-error
## Test plan
- [x] 13 new unit tests covering all three functions × all edge cases
- [x] `npx vitest run src/cron/isolated-agent/helpers.test.ts` — all pass
- [x] Full test suite — 8157 passed, 2 pre-existing failures (unrelated: `status.test.ts`, `model-catalog.test.ts`)
- [x] `pnpm build` — clean
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixes cron summaries and deliveries showing error messages instead of actual agent output by implementing two-pass selection in `pickSummaryFromPayloads`, `pickLastNonEmptyTextFromPayloads`, and `pickLastDeliverablePayload`. The root cause was that `buildEmbeddedRunPayloads` appends `isError: true` warnings (tool errors, rate limits, billing issues) as the last payload, and these three functions iterate last-to-first, incorrectly picking errors over real content.
**Key changes:**
- All three functions now skip `isError: true` entries in the first pass, only picking real agent output
- Second pass includes error entries as fallback, so error-only runs still get summaries
- Added `isError?: boolean` to type signatures and `DeliveryPayload` type
- Edge cases handled: mixed payloads pick real text, error-only returns error, `isError: undefined` treated as non-error
**Test coverage:**
- 13 new unit tests covering all three functions and edge cases
- Tests confirm real content is preferred over errors, error fallback works, and empty payloads return undefined
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk - it's a targeted bug fix with comprehensive test coverage
- The fix is well-designed with a clean two-pass approach that preserves backward compatibility. All three modified functions follow the same pattern (skip errors first, fallback to errors second), making the logic easy to understand and maintain. The 13 new unit tests cover all edge cases including mixed payloads, error-only payloads, empty arrays, and undefined handling. The PR author verified all tests pass (8157 passed) and the build is clean. The implementation correctly handles the root cause without introducing new dependencies or breaking changes.
- No files require special attention
<sub>Last reviewed commit: 8f27286</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#19339: fix(heartbeat): skip isError payloads when resolving heartbeat reply
by aldoeliacim · 2026-02-17
80.5%
#6522: fix(cron): deliver original message when agent response is heartbea...
by sidmohan0 · 2026-02-01
80.4%
#19406: fix(heartbeat): filter error payloads from heartbeat reply selection
by namabile · 2026-02-17
80.4%
#17950: fix: filter error payloads from user-facing messages
by Suksham-sharma · 2026-02-16
78.5%
#20329: Fix cron.run WS blocking and harden delivery recovery
by guirguispierre · 2026-02-18
78.2%
#21014: fix(cron): suppress main-session summary for HEARTBEAT_OK responses
by nickjlamb · 2026-02-19
77.8%
#23086: fix(cron): surface channel resolution error for isolated sessions w...
by hydro13 · 2026-02-22
77.5%
#22845: Pass agentDir through cron and followup embedded runs
by seilk · 2026-02-21
75.7%
#11216: Fix nightly failures: cron webchat delivery result + media cleanup ...
by DeanoC · 2026-02-07
75.7%
#13383: fix(cron): route text-only payloads through direct delivery
by Masha-L · 2026-02-10
75.3%