warpdotdev/warp · error · anyhow::Error
Failed to delete schedule: {}
Error message
Failed to delete schedule: {} What it means
delete_schedule stores the oneshot sender in self.pending_deletes and the returned future awaits the receiver. If the sender is dropped without ever completing the channel - because the ScheduledAgentManager entity was dropped (app quit) or the sync path that resolves pending_deletes removed the entry without sending - rx.await returns RecvError ('channel closed'), which this message wraps.
Source
Thrown at app/src/ai/ambient_agents/scheduled.rs:387
Some(schedule) => {
if schedule.metadata().has_pending_online_only_change()
|| schedule.metadata().pending_changes_statuses.pending_delete
{
let _ = tx.send(Err(anyhow::anyhow!(
"Cannot delete schedule with pending changes"
)));
} else {
self.pending_deletes.insert(schedule_id, tx);
UpdateManager::handle(ctx).update(ctx, |update_manager, ctx| {
update_manager.delete_object_by_user(id_and_type, ctx);
});
}
}
}
async move {
rx.await
.map_err(|e| anyhow::anyhow!("Failed to delete schedule: {}", e))?
}
}
}
impl Entity for ScheduledAgentManager {
type Event = ();
}
impl SingletonEntity for ScheduledAgentManager {}
View on GitHub (pinned to e72fd7aacb)
Solutions
- Retry delete_schedule after re-checking that the schedule still exists locally
- Verify server-side state first: if the object was actually deleted, refresh instead of retrying
- Ensure the app is not torn down while pending_deletes is non-empty (drain on shutdown)
- Fix or report any sync code path that removes a pending_deletes entry without sending a result
Example fix
// before
manager.delete_schedule(schedule_id, ctx).await?;
// after
match manager.delete_schedule(schedule_id, ctx).await {
Ok(()) => Ok(()),
Err(e) if e.to_string().starts_with("Failed to delete schedule") => {
// channel closed before the ack: verify and retry once
verify_schedule_gone_server_side(&schedule_id).await?;
manager.delete_schedule(schedule_id, ctx).await
}
Err(e) => Err(e),
} Defensive patterns
Strategy: retry
Validate before calling
if manager.pending_deletes.contains_key(&schedule_id) {
// a delete is already awaiting its ack; don't start a second one
} Try / catch
match manager.delete_schedule(id, ctx).await {
Err(e) if e.to_string().starts_with("Failed to delete schedule") => {
verify_server_side_gone(&id).await; // avoid deleting a recreated schedule
manager.delete_schedule(id, ctx).await
}
other => other,
} Prevention
- Drain or persist pending_deletes on shutdown instead of dropping the channels
- Ensure every code path that removes a pending_deletes entry sends a final result
- Keep the manager entity alive until in-flight cloud mutations resolve
When it happens
Trigger: The pending_deletes entry keyed by schedule_id is dropped unresolved: app shutdown mid-delete, sync failure path that never sends on the stored tx, or the manager entity being recreated before the cloud delete acknowledgement arrives.
Common situations: Quitting Warp while a schedule deletion is awaiting server confirmation; connectivity loss where the delete ack never arrives and the channel is cleaned up; entity reset during logout/login while deletes are in flight.
Related errors
- Schedule not found
- Schedule {schedule_id} not found
- Cannot delete schedule with pending changes
- Cloud follow-up did not start in time
- Cloud agent failed
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/b956d290c1b73f5d.
Report an issue: GitHub.