wasmerio/wasmer · error · anyhow::Error

invocation start must not be after end

Error message

invocation start must not be after end

What it means

default_cron_invocation_window computes the (start, end) time window used when querying cron job invocations, defaulting end=now / start=now-31 days when both bounds are omitted. If the caller supplies a start after end, it bails with 'invocation start must not be after end' as input validation.

Source

Thrown at lib/backend-api/src/query.rs:602

    Ok(logs_from_connection(invocation.logs))
}

fn default_cron_invocation_window(
    start: Option<OffsetDateTime>,
    end: Option<OffsetDateTime>,
) -> Result<(OffsetDateTime, OffsetDateTime), anyhow::Error> {
    let (start, end) = match (start, end) {
        (Some(start), Some(end)) => (start, end),
        (Some(start), None) => (start, OffsetDateTime::now_utc()),
        (None, Some(end)) => (end - time::Duration::days(31), end),
        (None, None) => {
            let end = OffsetDateTime::now_utc();
            (end - time::Duration::days(31), end)
        }
    };
    if start > end {
        bail!("invocation start must not be after end");
    }
    Ok((start, end))
}

fn logs_from_connection(connection: types::CronJobLogConnection) -> Vec<types::CronJobLog> {
    connection
        .edges
        .into_iter()
        .flatten()
        .filter_map(|edge| edge.node)
        .collect()
}

/// Load the S3 credentials.
///
/// S3 can be used to get access to an apps volumes.
pub async fn get_app_s3_credentials(
    client: &WasmerClient,

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Swap/order the timestamps so start <= end before calling the API.
  2. Normalize both timestamps to UTC (OffsetDateTime::now_utc() comparisons) and strip incompatible offsets.
  3. Add a clamp helper: if start > end, either error early in your code or clamp to a 31-day default window.

Example fix

// before
let window = (end_ts, start_ts); // reversed
let page = get_cron_job_invocations_page(&client, name, window).await?;
// after
let (start, end) = if start_ts > end_ts { (end_ts, start_ts) } else { (start_ts, end_ts) };
let page = get_cron_job_invocations_page(&client, name, (start, end)).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn valid_window(start: OffsetDateTime, end: OffsetDateTime) -> bool { start <= end }
// or clamp: let (start, end) = if start > end { (end, start) } else { (start, end) };

Prevention

When it happens

Trigger: Calling get_cron_job_invocations_page or get_cron_job_invocations_page_by_id with an explicit window where start > end — e.g. swapped arguments, negative duration math, or passing future end times.

Common situations: Passing (end, start) in the wrong order; computing timestamps with timezone/DST mix-ups; using a clock-skewed host so now_utc() lands before the caller's start.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/040f5af1e43b8a9a. Report an issue: GitHub.