warpdotdev/warp · error · anyhow::Error

Schedule {schedule_id} not found

Error message

Schedule {schedule_id} not found

What it means

delete_schedule creates a oneshot result channel and looks the schedule up via CloudModel::as_ref(ctx).get_by_uid(&schedule_id.uid()). If the uid is absent it immediately completes the channel with this error, so the returned future resolves to it and UpdateManager::delete_object_by_user is never called.

Source

Thrown at app/src/ai/ambient_agents/scheduled.rs:367

        )
    }

    /// Delete a scheduled ambient agent.
    pub fn delete_schedule(
        &mut self,
        schedule_id: SyncId,
        ctx: &mut ModelContext<Self>,
    ) -> impl Future<Output = anyhow::Result<()>> + Send + 'static + use<> {
        let id_and_type = CloudObjectTypeAndId::GenericStringObject {
            object_type: GenericStringObjectFormat::Json(JsonObjectType::ScheduledAmbientAgent),
            id: schedule_id,
        };

        let (tx, rx) = oneshot::channel();

        match CloudModel::as_ref(ctx).get_by_uid(&schedule_id.uid()) {
            None => {
                let _ = tx.send(Err(anyhow::anyhow!("Schedule {schedule_id} not found")));
            }
            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 {

View on GitHub (pinned to e72fd7aacb)

Solutions

  1. Re-sync cloud objects (or re-open the schedules surface) and retry with a live id
  2. Pre-validate with CloudModel::as_ref(ctx).get_by_uid(&schedule_id.uid()) before deleting
  3. If the goal is only that the schedule be gone, treat this error as idempotent success

Example fix

// before
manager.delete_schedule(schedule_id, ctx).await?;

// after
let gone = CloudModel::as_ref(ctx)
    .get_by_uid(&schedule_id.uid())
    .is_none();
if gone {
    return Ok(()); // already deleted: idempotent no-op
}
manager.delete_schedule(schedule_id, ctx).await?;
Defensive patterns

Strategy: validation

Validate before calling

if CloudModel::as_ref(ctx).get_by_uid(&schedule_id.uid()).is_none() {
    return Ok(()); // already gone: treat delete as idempotent
}

Type guard

fn schedule_present(id: &SyncId, ctx: &AppContext) -> bool {
    CloudModel::as_ref(ctx).get_by_uid(&id.uid()).is_some()
}

Try / catch

match manager.delete_schedule(id, ctx).await {
    Err(e) if e.to_string().contains("not found") => Ok(()), // idempotent delete
    other => other,
}

Prevention

When it happens

Trigger: Invoking ScheduledAgentManager::delete_schedule with a SyncId whose uid is not present in the local CloudModel snapshot (the None arm at scheduled.rs:368).

Common situations: Double-delete from UI (first delete removed the object, second resolves to this error); schedule deleted on another machine and the local snapshot is stale; object evicted before sync completed after re-login or workspace switch.

Related errors


AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16). Data as JSON: /api/errors/f33507278ae2b512. Report an issue: GitHub.