Hmbown/CodeWhale · warning

Timed out waiting for task

Error message

Timed out waiting for task {task_id}

What it means

A wait helper polls the task every 50 ms via get_task until its status is terminal; if the deadline passes first it throws 'Timed out waiting for task {task_id}'. It signals that the task did not reach a terminal state within the allowed timeout, not that the task failed itself.

Solutions

  1. Check the task's current status with get_task/list — it may still be running; re-wait with a longer deadline if progress is being made.
  2. Cancel or reap the stuck task if it is genuinely hung, then retry the work.
  3. Investigate the task's own logs for a deadlock or blocking call that prevents reaching a terminal state.

Example fix

// before
let task = manager.wait_for_task(id, Duration::from_secs(30)).await?;
// after
let task = match manager.wait_for_task(id, Duration::from_secs(30)).await {
    Ok(t) => t,
    Err(_) => { manager.cancel_task(id).await?; manager.wait_for_task(id, Duration::from_secs(30)).await? }
};
Defensive patterns

Strategy: retry

Try / catch

let task = match manager.wait_for_task(id, timeout).await {
    Ok(t) => t,
    Err(e) if e.to_string().contains("Timed out waiting") => {
        // inspect status, extend deadline or cancel
        manager.cancel_task(id).await?;
        return Err(e);
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Awaiting task completion with a timeout that expires while the task is still running or stuck in a non-terminal status (queued/running).

Common situations: Long-running subagent work exceeding the default wait budget; a hung task (deadlocked tool, stalled network call); system under heavy load slowing the task loop.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/4e5633a0ec5999d5. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/task_manager.rs:3480

    }
    primary
}

/// Wait for a task to reach a terminal status (tests and API helpers).
#[cfg(test)]
pub async fn wait_for_terminal_state(
    manager: &TaskManager,
    task_id: &str,
    timeout: StdDuration,
) -> Result<TaskRecord> {
    let deadline = std::time::Instant::now() + timeout;
    loop {
        let task = manager.get_task(task_id).await?;
        if task.status.is_terminal() {
            return Ok(task);
        }
        if std::time::Instant::now() >= deadline {
            bail!("Timed out waiting for task {task_id}");
        }
        sleep(StdDuration::from_millis(50)).await;
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::test_support::{EnvVarGuard, lock_test_env};
    use std::fs;
    use std::sync::atomic::{AtomicUsize, Ordering};
    use tokio::time::Duration;

    struct MockExecutor;

    fn provider_default_model_cases() -> Vec<(&'static str, Config, &'static str)> {
        let deepseek = Config {
            provider: Some("deepseek".to_string()),

View on GitHub (pinned to 73e0f67d83)