Hmbown/CodeWhale · error
attempt finalization status must be terminal
Error message
attempt finalization status must be terminal
What it means
FleetLedger::finalize_task_attempt_if_leased accepts an optional final_status that is written into the TaskAttemptFinalized record. If final_status is Some but is not a terminal ledger status (Completed/Failed/Cancelled), the guard at crates/tui/src/fleet/ledger.rs:975 rejects the call: finalizing an attempt into a non-terminal status (e.g. Leased, Queued) would corrupt the ledger state machine. Passing None is allowed (keep the event-derived status).
Solutions
- Pass final_status = None to keep the status derived from the terminal event itself.
- Set final_status only to FleetTaskLedgerStatus::Completed, Failed, or Cancelled.
- Fix the status-mapping function so it produces a terminal variant for finalize calls.
Example fix
// before
let final_status = Some(FleetTaskLedgerStatus::Leased);
ledger.finalize_task_attempt_if_leased(&run_id, &w, &t, attempts, &ts, payload, final_status, receipt)?;
// after
let final_status = Some(match outcome {
Outcome::Done => FleetTaskLedgerStatus::Completed,
Outcome::Err => FleetTaskLedgerStatus::Failed,
Outcome::Stopped => FleetTaskLedgerStatus::Cancelled,
});
ledger.finalize_task_attempt_if_leased(&run_id, &w, &t, attempts, &ts, payload, final_status, receipt)?; Defensive patterns
Strategy: validation
Validate before calling
if let Some(s) = final_status {
assert!(matches!(s, FleetTaskLedgerStatus::Completed | FleetTaskLedgerStatus::Failed | FleetTaskLedgerStatus::Cancelled));
} Type guard
fn is_terminal_status(s: FleetTaskLedgerStatus) -> bool { matches!(s, FleetTaskLedgerStatus::Completed | FleetTaskLedgerStatus::Failed | FleetTaskLedgerStatus::Cancelled) } Try / catch
if let Err(e) = finalize_result {
if e.to_string().contains("status must be terminal") { /* fix the status mapping, non-retryable */ }
} Prevention
- Prefer final_status = None and let the terminal event derive the status.
- Centralize outcome->status mapping in one function that only yields terminal variants.
- Update status-mapping code whenever FleetTaskLedgerStatus variants change.
When it happens
Trigger: Calling finalize_task_attempt_if_leased with final_status set to a non-terminal value such as FleetTaskLedgerStatus::Leased, Queued, or Running; mapping a worker outcome to the wrong status variant; a stale enum copied from a progress-update path.
Common situations: Status-mapping tables written before the terminal-only rule; refactors that renamed or re-ordered FleetTaskLedgerStatus variants; supervisor code that finalizes with the task's current status instead of the terminal outcome.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- attempt finalization requires a terminal worker event
- attempt receipt generation does not match its lease
- attempt receipt identity does not match its terminal event
- conditional progress append does not accept terminal worker…
- conditional terminal append requires a terminal worker event
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/88623235c7d92463.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/fleet/ledger.rs:975
mut receipt: FleetReceipt,
) -> Result<Option<FleetWorkerEvent>> {
if !matches!(
&payload,
FleetWorkerEventPayload::Completed { .. }
| FleetWorkerEventPayload::Failed { .. }
| FleetWorkerEventPayload::Cancelled { .. }
) {
bail!("attempt finalization requires a terminal worker event");
}
if final_status.is_some_and(|status| {
!matches!(
status,
FleetTaskLedgerStatus::Completed
| FleetTaskLedgerStatus::Failed
| FleetTaskLedgerStatus::Cancelled
)
}) {
bail!("attempt finalization status must be terminal");
}
if receipt.run_id != *run_id || receipt.task_id != task_id || receipt.worker_id != worker_id
{
bail!("attempt receipt identity does not match its terminal event");
}
if receipt
.attempt
.is_some_and(|attempt| attempt != expected_attempts)
{
bail!("attempt receipt generation does not match its lease");
}
self.with_write_lock(|| {
let state = self.rebuild_state_unlocked()?;
let key = task_key(&run_id.0, task_id);
let Some(task) = state.tasks.get(&key) else {
return Ok(None);
};
if task.status != FleetTaskLedgerStatus::LeasedView on GitHub (pinned to 73e0f67d83)