Hmbown/CodeWhale · error
conditional progress append does not accept terminal worker…
Error message
conditional progress append does not accept terminal worker events
What it means
append_event_if_leased is the conditional progress-append path: it appends a worker event only if the calling worker still holds the live lease. Terminal outcomes (Completed, Failed, Cancelled) have their own dedicated append paths and must never flow through this guard, so passing one is rejected up front before any lock is taken.
Solutions
- Route terminal payloads to the dedicated terminal append method on the ledger instead of append_event_if_leased.
- Match on the payload variant before choosing the append API: terminal variants take the terminal path, everything else the conditional path.
- If the event is produced during stream draining after cancellation, discard it — the lease guard exists precisely so post-cancellation output is not recorded.
- Update the call site so the terminal event is only constructed after the appropriate terminal append was already performed.
Example fix
// before
ledger.append_event_if_leased(&run, worker, task, attempts, ts, FleetWorkerEventPayload::Completed { .. })?;
// after
ledger.append_terminal_event(&run, worker, task, ts, FleetWorkerEventPayload::Completed { .. })?; Defensive patterns
Strategy: type-guard
Validate before calling
// Refuse terminal payloads before calling the conditional API
fn is_terminal(p: &FleetWorkerEventPayload) -> bool {
matches!(p, FleetWorkerEventPayload::Completed { .. }
| FleetWorkerEventPayload::Failed { .. }
| FleetWorkerEventPayload::Cancelled { .. })
}
if is_terminal(&payload) { return append_terminal(payload); } Type guard
fn is_terminal(p: &FleetWorkerEventPayload) -> bool {
matches!(p, FleetWorkerEventPayload::Completed { .. }
| FleetWorkerEventPayload::Failed { .. }
| FleetWorkerEventPayload::Cancelled { .. })
} Try / catch
Err(e) if e.to_string().contains("does not accept terminal worker events") =>
eprintln!("bug: route terminal payloads to the terminal append API"); Prevention
- Split event emitters so progress and terminal events use distinct call sites.
- Add a debug assertion or unit test that no terminal variant reaches conditional appends.
- Discard post-cancellation drained output instead of appending it.
When it happens
Trigger: Calling `FleetLedger::append_event_if_leased` with a payload matching FleetWorkerEventPayload::Completed, Failed, or Cancelled.
Common situations: A worker draining its stream after cancellation built a final event and mistakenly passed it to the leased-guarded append instead of the terminal append API; refactored code routed all events through one helper; a host-shutdown path reused the progress append for final results.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- attempt finalization requires a terminal worker event
- attempt finalization status must be terminal
- attempt receipt generation does not match its lease
- attempt receipt identity does not match its terminal event
- conditional terminal append requires a terminal worker event
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/f3fe04667f3d90e5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/fleet/ledger.rs:810
/// Append progress only while this exact worker still owns the live lease.
/// Host startup and stream draining use this guard so output produced after
/// an out-of-process cancellation cannot become durable task progress.
pub fn append_event_if_leased(
&self,
run_id: &FleetRunId,
worker_id: &str,
task_id: &str,
expected_attempts: u32,
timestamp: &str,
payload: FleetWorkerEventPayload,
) -> Result<Option<FleetWorkerEvent>> {
if matches!(
&payload,
FleetWorkerEventPayload::Completed { .. }
| FleetWorkerEventPayload::Failed { .. }
| FleetWorkerEventPayload::Cancelled { .. }
) {
bail!("conditional progress append does not accept terminal worker events");
}
let appended = 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::Leased
|| task.leased_to.as_deref() != Some(worker_id)
|| task.entry.attempts != expected_attempts
{
return Ok(None);
}
let event = next_worker_event(&state, run_id, worker_id, task_id, timestamp, payload);
self.append_record_unlocked(&FleetLedgerRecord::EventAppended {
event: event.clone(),
})?;
Ok(Some(event))View on GitHub (pinned to 73e0f67d83)