Skip to content

fix(cron): preserve successful run status after delivery failure#105215

Merged
steipete merged 8 commits into
mainfrom
codex/pr-95419-replacement
Jul 12, 2026
Merged

fix(cron): preserve successful run status after delivery failure#105215
steipete merged 8 commits into
mainfrom
codex/pr-95419-replacement

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

Replaces #95419 on current main and fixes #94058. A successful isolated cron execution was reported as status=error when its later delivery failed, conflating execution outcome with delivery outcome. Some best-effort and startup catch-up paths also dropped the delivery error entirely.

Why This Change Was Made

The final implementation keeps execution and delivery as separate state dimensions. Successful execution remains status=ok; delivered, deliveryAttempted, and deliveryError carry post-run delivery state. It reclassifies the authoritative final result in place so final output and diagnostics survive, carries best-effort failures through the dispatcher, and preserves the error through startup catch-up projection.

This preserves the contributor commits from @Alix-007 and adds maintainer fixes for final-output preservation, single-copy diagnostics, best-effort delivery errors, and startup catch-up persistence.

User Impact

Cron history and events no longer claim a successful agent run failed solely because delivery failed. Operators still see the undelivered state and its specific error in run logs, including required, best-effort, scheduled, manual, and startup catch-up paths.

Evidence

  • Blacksmith Testbox tbx_01kxarzcsm09k7x7yfpdkm2rae: 261 focused cron tests passed across seven files.
  • Same Testbox: pnpm tsgo:core and pnpm tsgo:test:src passed.
  • Sanitized AWS contributor-head proof: run run_4eb146ece579, 177 focused tests passed.
  • Fresh autoreview iterations found and drove fixes for startup catch-up, best-effort error loss, target-resolution refusal, and removed-job terminal events; final review is clean with no actionable findings.

Closes #94058.
Supersedes #95419 and #94116.

Alix-007 and others added 7 commits July 12, 2026 02:00
A successful isolated cron agentTurn whose post-run delivery phase returns
an error collapsed the execution status into the delivery error, so the
outer scheduled run persisted status=error even though the isolated session
ended successfully.

Decouple execution status from delivery outcome in finalizeCronRun: when the
agent payload is non-fatal and the run was not aborted, a delivery dispatch
error now keeps status=ok and records the failure separately via
delivered/deliveryAttempted plus delivery diagnostics, which drive the
already-decoupled run-log deliveryStatus (not-delivered). Aborted runs and
fatal agent payloads keep their error status.

Fixes #94058
The #94058 fix kept isolated turn status=ok when post-run delivery
fails, but the broad `status === "error"` check also caught the
#91613 keyless implicit last-target refusal, which is a deliberate
delivery-target guard (errorKind "delivery-target") and must stay
status=error. Exclude that errorKind so genuine delivery dispatch
failures still become ok while target-guard refusals remain errors.
A successful isolated agent turn keeps status=ok when post-run delivery
fails (#94058), but the ok/not-delivered resolveRunOutcome branch only
forwarded delivery diagnostics and dropped the delivery dispatch error.
That left lastDeliveryError empty and the finished-event deliveryError
field blank, so CLI/UI/API run logs could not show why delivery did not
land for an otherwise successful run.

Thread the delivery error on a dedicated CronRunOutcome.deliveryError
field from resolveRunOutcome through executeDetachedCronJob and
applyJobResult into resolveDeliveryState, so it persists as
lastDeliveryError and reaches the finished event (and thus the run log)
without conflating it with a run-level error (lastError stays empty on a
successful run).

Add a service/run-log readback test proving the delivery error survives
the cron boundary into a persisted run-log entry, and extend the
isolated-turn regression to assert the dedicated deliveryError field.
@openclaw-barnacle openclaw-barnacle Bot added size: M maintainer Maintainer-authored PR labels Jul 12, 2026
@steipete
steipete requested a review from a team as a code owner July 12, 2026 09:11
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime cli CLI command changes scripts Repository scripts agents Agent runtime and tooling plugin: file-transfer size: XL and removed size: M labels Jul 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 83c7425ab3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread CHANGELOG.md

- **Gradium TTS credential egress:** reject non-HTTPS, foreign-host, and hostname-lookalike base URLs before dispatching API keys, and pin guarded transport to Gradium's documented API hostname. (#101280) Thanks @zhangguiping-xydt.
- **Gateway command SecretRefs:** preserve authoritative active-snapshot values when another command secret remains unresolved, falling back locally only for missing paths instead of emitting a per-turn `secrets.resolve` failure. (#96661) Thanks @SunnyShu0925.
- **Cron delivery status:** keep successful isolated agent turns at `status=ok` when downstream delivery fails, while preserving the send failure separately in delivery state and run logs. (#95419) Thanks @Alix-007.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the normal-fix changelog entry

The root AGENTS.md Docs/Changelog policy says CHANGELOG.md is release-only and normal fixes should put release-note context in the PR body or squash/direct commit message instead. Since this commit is a regular cron fix rather than a release-generation change, adding this line can leave stale or duplicated release notes when the generated changelog is refreshed; please drop the direct changelog edit and keep the note in the commit/PR metadata.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor Author

Land-ready maintainer proof:

  • Keeps successful isolated cron execution at status=ok when only downstream delivery fails, with delivered=false, deliveryAttempted, and deliveryError retained separately.
  • Covers required and best-effort sends, target-resolution refusal, scheduled/manual persistence, startup catch-up, removed-job fallback events, diagnostics, and run-log readback.
  • Blacksmith Testbox tbx_01kxarzcsm09k7x7yfpdkm2rae: 261 focused tests passed across seven cron suites; pnpm tsgo:core and pnpm tsgo:test:src passed.
  • Sanitized AWS original-head proof run_4eb146ece579: 177 focused tests passed.
  • Fresh final autoreview: clean, no actionable findings (0.91 confidence).
  • Repo-native review artifacts: READY FOR /prepare-pr, zero findings.
  • Full exact-head hosted CI and repo-native prepare gate passed for 95532797b19221015ed80a2f03f204390e516ff9.

This replacement preserves @Alix-007's contributor commits and adds the cross-path fixes required by review.

@steipete
steipete merged commit 9bdb2a5 into main Jul 12, 2026
170 of 176 checks passed
@steipete
steipete deleted the codex/pr-95419-replacement branch July 12, 2026 09:20
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 13, 2026
…nclaw#105215)

* fix(cron): keep isolated run status ok when delivery fails

A successful isolated cron agentTurn whose post-run delivery phase returns
an error collapsed the execution status into the delivery error, so the
outer scheduled run persisted status=error even though the isolated session
ended successfully.

Decouple execution status from delivery outcome in finalizeCronRun: when the
agent payload is non-fatal and the run was not aborted, a delivery dispatch
error now keeps status=ok and records the failure separately via
delivered/deliveryAttempted plus delivery diagnostics, which drive the
already-decoupled run-log deliveryStatus (not-delivered). Aborted runs and
fatal agent payloads keep their error status.

Fixes openclaw#94058

* fix(cron): keep deliberate delivery-target refusals as error status

The openclaw#94058 fix kept isolated turn status=ok when post-run delivery
fails, but the broad `status === "error"` check also caught the
openclaw#91613 keyless implicit last-target refusal, which is a deliberate
delivery-target guard (errorKind "delivery-target") and must stay
status=error. Exclude that errorKind so genuine delivery dispatch
failures still become ok while target-guard refusals remain errors.

* fix(cron): surface successful run delivery errors to run logs

A successful isolated agent turn keeps status=ok when post-run delivery
fails (openclaw#94058), but the ok/not-delivered resolveRunOutcome branch only
forwarded delivery diagnostics and dropped the delivery dispatch error.
That left lastDeliveryError empty and the finished-event deliveryError
field blank, so CLI/UI/API run logs could not show why delivery did not
land for an otherwise successful run.

Thread the delivery error on a dedicated CronRunOutcome.deliveryError
field from resolveRunOutcome through executeDetachedCronJob and
applyJobResult into resolveDeliveryState, so it persists as
lastDeliveryError and reaches the finished event (and thus the run log)
without conflating it with a run-level error (lastError stays empty on a
successful run).

Add a service/run-log readback test proving the delivery error survives
the cron boundary into a persisted run-log entry, and extend the
isolated-turn regression to assert the dedicated deliveryError field.

* fix(cron): preserve successful delivery outcomes

* fix(cron): preserve startup delivery errors

* fix(cron): retain best-effort delivery errors

* fix(cron): preserve delivery errors on fallback paths

* fix(cron): preserve delivery errors on fallback paths

---------

Co-authored-by: Alix-007 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: macos App: macos app: web-ui App: web-ui cli CLI command changes docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR plugin: file-transfer scripts Repository scripts size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Scheduled isolated agentTurn outer run records error although session ended success

2 participants