Skip to content

CronDataIntervalTimetable: first run delayed ~2 periods when start_date falls mid-period (catchup=False) #72380

Description

@avanish-garg

Description

Correction (2026-09-02): the original version of this issue was wrong about the common case —
see below.
I originally claimed CronDataIntervalTimetable/DeltaDataIntervalTimetable "always
wait for the next boundary" on first run under catchup=False, by analogy with
CronTriggerTimetable's run_immediately parameter. I verified this against actual runtime
behavior instead of just reading docstrings, and that claim is false for the two most common
setups: no explicit start_date, or a start_date from long in the past. In both cases,
CronDataIntervalTimetable._skip_to_latest() already schedules the most-recently-completed period
immediately — functionally equivalent to run_immediately=True by default, no toggle needed.

There is a real, much narrower edge case, though: when start_date is set to a value that falls
inside the currently in-progress period (e.g. deploying a DAG with start_date a few hours
ago, catchup=False), _align_to_next(earliest) skips the in-progress period entirely — it only
considers periods that start at or after start_date — which pushes the first run out to nearly
two full periods later, not one. Concretely, for @daily, deploying at start_date = now - 3h today doesn't produce a first run for today's or tomorrow's data, it produces one for the
day-after-tomorrow.

Verified with a script run through breeze testing core-tests, calling
CronDataIntervalTimetable("@daily", timezone="UTC").next_dagrun_info(...) directly with
last_automated_data_interval=None, restriction.catchup=False:

start_date first run's data interval delay
None yesterday → today (already complete) none — fires immediately
long in the past yesterday → today (already complete) none — fires immediately
now - 3h (today) day-after-tomorrow's full period ~2 periods

Use case/motivation

I don't know if this is intentional (only ever run "clean" full periods that start entirely after
start_date, never a period the DAG only existed for part of) or an oversight — I couldn't find
prior discussion either way. If it's intentional, this issue should probably just be closed. If
not, the CronTriggerTimetable-style _calc_first_run() — which chooses between the past-tick and
next-tick based on run_immediately / proximity — is a fix pattern already proven for the trigger
timetables and could plausibly be adapted rather than invented fresh, though I haven't scoped that
out since it depends on the answer above.

Apologies for the churn on the original framing — flagging here rather than silently closing so
there's a record of what was actually verified, in case the mid-period edge case is useful signal.

Related issues

None found.

Are you willing to submit a PR?

  • Yes I am willing to submit a PR!

(Holding off on a PR until there's a read on whether the mid-period behavior above is intended.)

Code of Conduct

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions