Hmbown/CodeWhale · error · anyhow::Error

Failed to promote staged task {}: {promote_err}

Error message

Failed to promote staged task {}: {promote_err}

What it means

The final step of the staged task-create transaction failed: atomically renaming tasks/.<id>.json.pending to tasks/<id>.json (the promote) returned an error. On failure the code rolls the queue back to its previous persisted state and deletes the staged file; if those cleanup operations also fail, their errors are appended to the message ('queue rollback also failed', 'ignored staged-file cleanup also failed').

Source

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

                        "failed to remove ignored staged task after queue write failure"
                    );
                }
                return Err(err);
            }
            if let Err(promote_err) = fs::rename(&staged_task_path, &task_path) {
                let rollback_error = self.persist_queue_locked(&state.queue).err();
                let cleanup_error = fs::remove_file(&staged_task_path).err();
                let mut message =
                    format!("Failed to promote staged task {}: {promote_err}", task.id);
                if let Some(rollback_error) = rollback_error {
                    message.push_str(&format!("; queue rollback also failed: {rollback_error:#}"));
                }
                if let Some(cleanup_error) = cleanup_error {
                    message.push_str(&format!(
                        "; ignored staged-file cleanup also failed: {cleanup_error}"
                    ));
                }
                bail!(message);
            }
            state.queue = next_queue;
            state.tasks.insert(task.id.clone(), task.clone());
        }
        self.notify.notify_one();
        Ok(task)
    }

    /// List tasks, newest first.
    pub async fn list_tasks(&self, limit: Option<usize>) -> Vec<TaskSummary> {
        self.list_tasks_scoped(limit, None).await
    }

    /// List tasks, newest first, optionally scoped to a workspace.
    pub async fn list_tasks_scoped(
        &self,
        limit: Option<usize>,
        workspace: Option<&Path>,

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Check disk space and write permission on the tasks directory; free space or fix ownership, then retry with a new id.
  2. If the message includes 'queue rollback also failed', compare queue state on disk with the running instance; prefer restarting the app in that directory over manually editing the queue.
  3. Remove a leftover .<id>.json.pending only after confirming tasks/<id>.json does not exist, then re-create the task with a fresh id.
  4. Ensure only one process owns a tasks_dir; concurrent writers make promotes and rollbacks interleave.
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight the exact operations the promote needs:
fn can_promote(tasks_dir: &Path) -> bool {
    let probe = tasks_dir.join(format!(".probe.{}.pending", std::process::id()));
    let ok = fs::write(&probe, b"").is_ok() && fs::rename(&probe, tasks_dir.join(".probe.json")).is_ok();
    let _ = fs::remove_file(tasks_dir.join(".probe.json"));
    ok
}

Try / catch

match tm.add_task_with_id(req, id).await {
    Err(e) if e.to_string().starts_with("Failed to promote staged task") => {
        // inspect disk space / perms, then retry ONCE with a new id;
        // if the message contains 'queue rollback also failed', restart the app instead
        retry_with_fresh_id(req).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Filesystem-level promote failure: disk full, permission changed on tasks_dir between staging and rename, the directory removed underneath the process, or antivirus/monitor renaming the file. The appended rollback errors mean the queue file or .pending debris could not be restored either.

Common situations: Disk exhaustion while creating tasks; tasks dir on a network mount that went away; sandboxed environments that deny rename; two instances pointed at the same tasks_dir.

Related errors


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