Skip to content

fix(workflow_scheduler): normalize naive/aware datetime comparison to tz-aware UTC (#12453) - #12457

Merged
mrveiss merged 1 commit into
Dev_new_guifrom
issue-12453
Jul 25, 2026
Merged

mrveiss merged 1 commit into
Dev_new_guifrom
issue-12453

Conversation

@mrveiss

@mrveiss mrveiss commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Thinking Path

Bug #12453 (surfaced by #12452 making workflow_scheduler_e2e_test.py runnable): services/workflow_scheduler.py raises TypeError: can't compare offset-naive and offset-aware datetimes at runtime.

Traced every scheduled_time origin: string inputs already go through parse_utc_iso/_parse_time_string, both of which return tz-aware datetimes (naive strings are assumed UTC, matching the codebase convention documented in autobot_shared/time_utils.py). The gap: when a caller passes a datetime object directly (e.g. datetime.now(), which is naive) to schedule_workflow() or reschedule_workflow(), it was stored as-is with no normalization. Later comparisons against datetime.now(tz=timezone.utc) in get_scheduler_status() (line 758), list_scheduled_workflows()'s sort key, _process_scheduled_workflows(), and _calculate_priority_score() then mix naive and aware values and raise TypeError.

What Changed

  • Added _ensure_utc_aware(value: datetime) -> datetime helper in autobot-backend/workflow_scheduler.py, following the same "naive is assumed UTC" convention as autobot_shared.time_utils.parse_utc_iso.
  • Applied it to the datetime-object branch of _parse_schedule_params (used by schedule_workflow) and reschedule_workflow, so every code path that stores a scheduled_time/new_time now guarantees a tz-aware UTC value — whether the input was a string or a naive datetime object.
  • Audited the rest of the file for other naive/aware comparison sites: none remain — _load_workflows/ScheduledWorkflow.from_dict already use parse_utc_iso, and every other datetime.now(...) call in the file already passes tz=timezone.utc.
  • No broad try/except added — this is a root-cause normalization fix, not error masking.

Verification

Reverted the fix locally (via git apply -R) to confirm it reproduces the reported bug, then re-applied:

Before fix — 2 failures, both TypeError: can't compare offset-naive and offset-aware datetimes (one at workflow_scheduler.py:745 inside list_scheduled_workflows's sort, one at workflow_scheduler.py:758 inside get_scheduler_status, exactly as described in #12453):

workflow_scheduler_e2e_test.py .F..F..                                   [100%]
FAILED workflow_scheduler_e2e_test.py::test_workflow_management - TypeError: ...
FAILED workflow_scheduler_e2e_test.py::test_scheduler_status - TypeError: can...
2 failed, 5 passed in 0.85s

After fix:

$ python3 -m pytest workflow_scheduler_e2e_test.py -p no:xdist -q
workflow_scheduler_e2e_test.py .......                                   [100%]
7 passed in 0.41s

black --check and flake8 --max-line-length=120 on the changed file: clean.

Model Used

Claude Sonnet 5

Closes #12453

… tz-aware UTC (#12453)

Naive datetime objects passed as scheduled_time/new_time (e.g. datetime.now()
from a caller) were never normalized to UTC, unlike the string path which
already went through parse_utc_iso/_parse_time_string. Later comparisons
against tz-aware now (get_scheduler_status, list_scheduled_workflows sort,
_process_scheduled_workflows, _calculate_priority_score) raised
TypeError: can't compare offset-naive and offset-aware datetimes.

Add _ensure_utc_aware() following the parse_utc_iso convention (naive is
assumed UTC) and apply it to the datetime-object branch of
_parse_schedule_params and reschedule_workflow.
@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No hardcoded values detected that have SSOT config equivalents!

@mrveiss
mrveiss merged commit b42b135 into Dev_new_gui Jul 25, 2026
39 checks passed
@mrveiss
mrveiss deleted the issue-12453 branch July 25, 2026 12:54
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.

1 participant