#6522: fix(cron): deliver original message when agent response is heartbeat-only
Cluster:
Cron Job Enhancements
## Summary
Fixes #6341 — When a cron job with `deliver: true` runs and the agent response is filtered as heartbeat-only (e.g. `HEARTBEAT_OK`), the scheduler silently returns `status: "ok"` without delivering anything. The user never receives their reminder.
## Root Cause
In `src/cron/isolated-agent/run.ts`, when `isHeartbeatOnlyResponse()` returns true, `skipHeartbeatDelivery` is set and the entire delivery block is bypassed. The original `params.message` (the reminder text from the job config) is never used as a fallback — it's simply discarded.
## Fix
When heartbeat filtering triggers and the job has a non-empty original message, substitute the original message as the delivery payload instead of skipping delivery entirely:
```typescript
if (skipHeartbeatDelivery && originalMessage) {
effectivePayloads = [{ text: originalMessage }];
skipHeartbeatDelivery = false;
}
```
This reuses the existing delivery block (channel routing, error handling, `bestEffortDeliver` logic) with zero duplication. When the original message is empty/whitespace, delivery is still skipped (no blank messages).
## What's NOT changed
- `helpers.ts` — `isHeartbeatOnlyResponse()` works correctly, no changes
- `delivery-target.ts` / `targets.ts` — separate issue (#6340)
- No other channels, no config changes, no type changes
- Heartbeat filtering still works for responses with substantial content (existing test unchanged)
## Testing
- [x] Updated `"skips delivery when response is exactly HEARTBEAT_OK"` → now expects fallback delivery of original message
- [x] Updated `"skips delivery when response has HEARTBEAT_OK with short padding"` → same
- [x] Added `"skips delivery when heartbeat response and original message is empty"` edge case
- [x] Existing `"delivers when response has HEARTBEAT_OK but also substantial content"` still passes (no change)
- [x] All 26 cron tests pass (3 test files)
- [x] `pnpm tsgo` — no type errors
- [x] `pnpm lint` — 0 warnings, 0 errors
- [x] `oxfmt --check` — clean
## AI Disclosure
Built with Claude (AI-assisted). Fully tested locally. I understand what the code does.
**Diff: 2 files, +67 / -9 lines.**
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the cron isolated-agent runner to avoid silently skipping delivery when the agent’s response is filtered as heartbeat-only (e.g., `HEARTBEAT_OK`) and `deliver: true` is set. In `src/cron/isolated-agent/run.ts`, it introduces an `effectivePayloads` fallback that substitutes the original cron job message (`params.message.trim()`) as the delivery payload when heartbeat filtering would otherwise skip delivery, preserving the existing outbound delivery pathway.
It also updates cron isolated-agent tests to assert this new behavior (deliver the original message on heartbeat-only responses) and adds an edge-case test to ensure delivery still skips when the original message is empty/whitespace.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- The change is narrowly scoped to cron delivery behavior when responses are heartbeat-only, reuses existing delivery plumbing, and is covered by updated and new tests for the fallback and whitespace edge case. No broader routing or type changes are introduced.
- No files require special attention
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#21014: fix(cron): suppress main-session summary for HEARTBEAT_OK responses
by nickjlamb · 2026-02-19
88.3%
#13383: fix(cron): route text-only payloads through direct delivery
by Masha-L · 2026-02-10
83.9%
#13638: fix: pass delivery context to cron isolated agent subagents
by dario-github · 2026-02-10
82.5%
#11216: Fix nightly failures: cron webchat delivery result + media cleanup ...
by DeanoC · 2026-02-07
82.4%
#11657: fix(cron): treat skipped heartbeat as ok for one-shot jobs
by DukeDeSouth · 2026-02-08
80.9%
#8307: fix(cron): improve tool description with reliable reminder guidance
by vishaltandale00 · 2026-02-03
80.7%
#3335: Fixes cron jobs
by hkirat · 2026-01-28
80.5%
#21454: fix(cron): skip isError payloads when picking summary/delivery content
by Diaspar4u · 2026-02-19
80.4%
#20521: feat(heartbeat): inject active cron job summary into heartbeat prompt
by maximalmargin · 2026-02-19
80.3%
#22707: fix: pass agentDir to runEmbeddedPiAgent in cron isolated sessions
by mrlerner · 2026-02-21
80.1%