Hmbown/CodeWhale · warning

worker {worker_id} no longer has that running fleet task

Error message

worker {worker_id} no longer has that running fleet task

What it means

FleetManager::interrupt_worker found an active task for the worker, but the ledger's cancel_task_if_active returned false, meaning the task was no longer active under that worker's lease at cancel time. This is a read-then-act race: between rebuilding state and cancelling, the task completed, was cancelled elsewhere, or its lease moved.

Source

Thrown at crates/tui/src/fleet/manager.rs:1018

    pub fn interrupt_worker(&self, worker_id: &str) -> Result<FleetWorkerInspection> {
        let state = self.ledger.rebuild_state()?;
        let Some(task) = active_task_for_worker(&state, worker_id) else {
            return Err(FleetControlError::NoActiveTask {
                worker_id: worker_id.to_string(),
            }
            .into());
        };
        let cancelled = self.ledger.cancel_task_if_active(
            &task.entry.run_id,
            &task.entry.task_id,
            Some(worker_id),
            &timestamp(),
            Some("operator"),
            Some("operator"),
        )?;
        if !cancelled {
            bail!("worker {worker_id} no longer has that running fleet task");
        }
        self.refresh_run_status(&task.entry.run_id)?;
        self.inspect_worker(worker_id)
    }

    pub fn restart_worker(&self, worker_id: &str) -> Result<FleetRestartReport> {
        let state = self.ledger.rebuild_state()?;
        let Some(task) = active_task_for_worker(&state, worker_id)
            .or_else(|| latest_task_for_worker(&state, worker_id))
        else {
            bail!("worker {worker_id} has no fleet task to restart");
        };
        let run = state
            .runs
            .get(&task.entry.run_id.0)
            .ok_or_else(|| anyhow!("fleet run {} does not exist", task.entry.run_id.0))?;
        let max_workers = run
            .max_workers

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Re-inspect the worker (inspect_worker) to see its current task/status; if terminal, no interrupt is needed
  2. Retry interrupt_worker if a new task is now active and still must be stopped
  3. Treat the error as benign idempotency noise when the goal was simply 'make it stop'
  4. Serialize operator commands per worker in UI/script code to avoid racing yourself

Example fix

// before
manager.interrupt_worker(&worker_id)?;

// after
match manager.interrupt_worker(&worker_id) {
    Ok(inspection) => { /* cancelled */ }
    Err(err) if err.to_string().contains("no longer has that running fleet task") => {
        let _ = manager.inspect_worker(&worker_id); // already moved on
    }
    Err(err) => return Err(err),
}
Defensive patterns

Strategy: try-catch

Try / catch

match manager.interrupt_worker(&worker_id) {
    Ok(inspection) => Ok(Some(inspection)),
    Err(err) if err.to_string().contains("no longer has that running fleet task") => {
        Ok(None) // task already moved on; idempotent success
    }
    Err(err) => Err(err),
}

Prevention

When it happens

Trigger: Calling interrupt_worker(worker_id) concurrently with the worker finishing its task, another operator cancelling it, or a lease expiring and being taken over.

Common situations: Clicking stop in the UI just as the task completes; scripts that interrupt several workers in a loop while the scheduler reassigns work; double-invoked interrupt from a keybinding repeat.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/129f056b284b26c5. Report an issue: GitHub.