influxdata/influxdb · error · PluginError

running a cron trigger that is finished.

Error message

running a cron trigger that is finished.

What it means

Raised by run_schedule_event_source_loop when the cron runner's schedule is exhausted (next_run_time yields an instant, but next_trigger_time is None), i.e. the loop woke for a scheduled instant but the schedule is finished and cannot provide a scheduled_at. Treated as an internal invariant violation via anyhow!, surfaced as PluginError.

Solutions

  1. Use an unbounded recurring cron expression (e.g. '0 * * * *') instead of a finite/one-shot schedule.
  2. Recreate the trigger with a fresh future schedule if a one-shot run was intended.
  3. If seen with a normal recurring schedule, check NTP clock sync and report upstream.

Example fix

// before
SCHEDULE '0 0 1 1 * 2026'  // bounded, finishes after last run
// after
SCHEDULE '0 0 1 1 *'       // recurring every Jan 1
Defensive patterns

Strategy: try-catch

Validate before calling

use cron::Schedule;
fn is_unbounded(expr: &str) -> bool {
    expr.parse::<Schedule>().map(|s| s.upcoming(chrono::Utc).take(5).count() == 5).unwrap_or(false)
}

Try / catch

if let Err(e) = run_schedule_event_source(...).await {
    if e.to_string().contains("finished") { recreate_trigger_with_recurring_schedule()?; }
}

Prevention

When it happens

Trigger: A cron schedule with a finite end date whose final run has been consumed; clock/time-provider anomalies where next_run_time and next_trigger_time disagree.

Common situations: Using a bounded cron schedule (cron crate supports 'TO' ranges/limited schedules) for a long-lived trigger; system clock changes.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/595f7a8201655d5d. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_processing_engine/src/plugins.rs:135

        }
    });

    Ok(())
}

async fn run_schedule_event_source_loop(
    mut runner: ScheduleTriggerRunner,
    time_provider: Arc<dyn TimeProvider>,
    scheduler: Scheduler,
    key: TriggerKey,
    cancel: CancellationToken,
) -> Result<(), PluginError> {
    while let Some(next_run_instant) = runner.next_run_time() {
        tokio::select! {
            _ = cancel.cancelled() => break,
            _ = time_provider.sleep_until(next_run_instant) => {
                let Some(scheduled_at) = runner.next_trigger_time else {
                    return Err(anyhow!("running a cron trigger that is finished.").into());
                };
                runner.advance_time();
                if scheduler
                    .enqueue(TriggerInvocation::new(
                        key,
                        TriggerPayload::Schedule { scheduled_at },
                    ))
                    .await
                    .is_err()
                {
                    break;
                }
            }
        }
    }
    Ok(())
}

View on GitHub (pinned to 06200ef96b)