Skip to content

Conversation

popojk
Copy link
Contributor

@popojk popojk commented Aug 14, 2025

Tracking issue

Related to #6470

Why are the changes needed?

In the Flytekit SDK, it is proposed that an error be raised if the user enters a cron job with an invalid date (e.g., 0 0 31 2 *), preventing the schedule from being sent to the backend.

What changes were proposed in this pull request?

Add schedule date validation check in flytekit SDK.

How was this patch tested?

Test workflow:

from datetime import datetime

from flytekit import task, workflow, CronSchedule, LaunchPlan


@task
def task_1(message: str) -> str:
    return message


@workflow
def date_formatter_wf2() -> str:
    return task_1("hello")

cron_lp = LaunchPlan.get_or_create(
    name="cron_scheduled_lp",
    workflow=date_formatter_wf2,
    schedule=CronSchedule(
        schedule="0 0 31 2 *",
    ),
)

After registering the launch_plan with invalid schedule date, the SDK throws error as expected.
截圖 2025-08-14 上午11 48 56

Check all the applicable boxes

  • All new and existing tests passed.
  • All commits are signed-off.

Summary by Bito

This pull request fixes a bug in the Flytekit SDK related to invalid cron date schedules that could cause an infinite loop by adding validation for cron schedules. It introduces error handling for invalid cron expressions and includes comprehensive tests to ensure correct behavior for both valid and invalid inputs, improving the scheduling feature's robustness.

# Check if the cron expression can actually produce valid dates
try:
# Try to get the next occurrence to validate the schedule
cron.get_next(datetime.datetime)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we combine this check with above so that we do not need to have two try...except block

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw is there any .validate() function that we can use instead of using get_next()?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest keeping them separate, and here's why:

  1. The first try block checks syntax: Whether schedule is a valid cron expression
  2. The second try block checks semantics: Whether the expression can generate valid dates

If they're combined together, the error handling would become generic and make it harder for users to pinpoint the actual problem.

@machichima, WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then how about adding Error: {str(e)} in the end of the error message?

While those two try...expect are just alike, I would still prefer merging them together. But I agree that we should print the error out here so that we know the actual problem

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable, let's merge them together and throw out the error message so users can understand whether it's a syntax error or semantic one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@machichima @JiangJiaWei1103 Thank you both for the advice. I've merged two try..except blocks into one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw is there any .validate() function that we can use instead of using get_next()?

@machichima I think the only way for croniter to validate cron date is calling get_next function. I'm not sure whether we can do the validation by others cron library, yet I prefer to keep using croniter as it is a simple way.

Comment on lines 162 to 167
invalid_schedules = [
"0 0 31 2 *", # February 31st (does not exist)
"0 0 30 2 *", # February 30th (does not exist)
"0 0 31 4 *", # April 31st (does not exist)
"0 0 31 6 *", # June 31st (does not exist)
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using @pytest.parametrize() to represent multiple test cases?

Copy link

codecov bot commented Aug 15, 2025

Codecov Report

❌ Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.15%. Comparing base (eb5a67f) to head (4faae88).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
flytekit/core/schedule.py 0.00% 4 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (eb5a67f) and HEAD (4faae88). Click for more details.

HEAD has 92 uploads less than BASE
Flag BASE (eb5a67f) HEAD (4faae88)
100 8
Additional details and impacted files
@@             Coverage Diff             @@
##           master    #3312       +/-   ##
===========================================
- Coverage   85.26%   41.15%   -44.11%     
===========================================
  Files         386      250      -136     
  Lines       30276    25038     -5238     
  Branches     2969     2950       -19     
===========================================
- Hits        25814    10304    -15510     
- Misses       3615    14631    +11016     
+ Partials      847      103      -744     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@machichima machichima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

cc @pingsutw

@pingsutw pingsutw merged commit 01a4987 into flyteorg:master Aug 16, 2025
225 of 230 checks passed
Atharva1723 pushed a commit to Atharva1723/flytekit that referenced this pull request Oct 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants