Hmbown/CodeWhale · error
Failed to promote staged task
Error message
Failed to promote staged task {task.id}: {promote_err} What it means
Promoting a staged (queued) task from its staging file into the active queue failed. Task_manager stages a task to disk first, then atomically promotes it; if promotion errors, it attempts a queue rollback and staged-file cleanup, and folds every secondary failure into one message so no failure is silently dropped. The task remains staged (or partially rolled back) — it was not activated.
Solutions
- Read the chained promote_err (plus rollback/cleanup notes) to identify the failing step.
- Check whether the staged task file still exists at the staged_task_path shown/derived from the queue directory.
- Fix the underlying cause (disk space, permissions, concurrent writer) and re-run promotion.
- If the staged file is orphaned and the queue is intact, remove the stale staged file manually and re-enqueue the task.
- Verify the queue schema version matches after a Codewhale upgrade.
Defensive patterns
Strategy: try-catch
Validate before calling
// before promoting, confirm the staged file exists and the queue is writable
if !tokio::fs::try_exists(&staged_task_path).await.unwrap_or(false) {
// staged file missing: re-stage or abort promotion
}
let md = tokio::fs::metadata(&queue_path).await?;
if md.permissions().readonly() {
// promotion would fail
} Try / catch
// Rust
match task_manager.promote(task_id).await {
Err(e) if e.to_string().contains("Failed to promote staged task") => {
// check rollback/cleanup notes in message; clear stale staged file; re-enqueue
}
other => other?,
} Prevention
- Do not delete or rename files in the task queue directory while the manager runs.
- Ensure a single writer owns the queue at a time.
- Keep disk space and permissions healthy on the queue directory.
- Re-verify staged task schema after upgrading.
When it happens
Trigger: `promote` of a staged task at task_manager.rs fails (queue write error, IO error on the queue file); the subsequent `tokio::fs::remove_file(&staged_task_path)` or queue rollback may also fail, each appending to the message.
Common situations: The queue store is locked by a concurrent writer; the staged file was deleted or renamed externally between staging and promotion; permission or disk-full errors; the staged task JSON no longer matches the queue's expected schema after an upgrade.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Control changed, but its restart preference could not be…
- already exists; pass --force to overwrite it
- Android loaded image
- approval log has no parent
- artifact name is not portable UTF-8
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/7e65dee9d17aa0e4.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/task_manager.rs:1834
{
tracing::warn!(
task_id = %task.id,
error = %cleanup_err,
"failed to remove ignored staged task after queue write failure"
);
}
return Err(err);
}
if let Err(promote_err) = tokio::fs::rename(&staged_task_path, &task_path).await {
let rollback_error = self.persist_queue_locked(&state.queue).err();
let cleanup_error = if recover_stage {
None
} else {
tokio::fs::remove_file(&staged_task_path).await.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>) -> Result<Vec<TaskSummary>> {View on GitHub (pinned to 73e0f67d83)