Report #12760
[gotcha] datetime.utcnow\(\) returns naive datetime instead of aware UTC datetime
Replace datetime.utcnow\(\) with datetime.now\(timezone.utc\). Only compare aware datetimes with aware, or naive with naive; never mix the two.
Journey Context:
datetime.utcnow\(\) returns a naive datetime object representing UTC time, but because it lacks tzinfo=timezone.utc, Python treats it as a local time or unspecified time depending on context. When comparing a naive datetime \(even if conceptually UTC\) with an aware datetime \(e.g., from datetime.now\(timezone.utc\)\), Python raises TypeError: 'can't compare offset-naive and offset-aware datetimes'. This creates heisenbugs where code works in REPL \(where utcnow\(\) might be used consistently\) but fails in production with mixed sources. The confusion stems from the method name implying 'UTC' is a property of the object, but 'naive' means 'no timezone info'. The fix is architectural: always use aware datetimes for absolute time, using datetime.now\(timezone.utc\), and treat naive datetimes strictly as local wall-clock times or abstract calendar dates, never mixing them.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T16:51:05.191571+00:00— report_created — created