From 73015e980e4b6dcceb7518adbce9f8436a13b27f Mon Sep 17 00:00:00 2001 From: Daniel Chalef <131175+danielchalef@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:28:56 -0700 Subject: [PATCH] Fix datetime comparison errors by normalizing to UTC (#988) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix datetime comparison errors by normalizing to UTC Applied ensure_utc() to all datetime comparisons in edge_operations.py to prevent TypeError when comparing timezone-naive and timezone-aware datetimes. Removed redundant tzinfo checks since ensure_utc() handles both None and naive datetimes. Fixed comparisons at: - Lines 419, 423: resolve_edge_contradictions function - Line 430: resolve_edge_contradictions function - Line 627: resolve_extracted_edge function (removed redundant tzinfo checks) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * Update uv.lock 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * Fix sorting with mixed timezone-aware/naive datetimes Normalize datetime to UTC in sort key to prevent TypeError when comparing mixed timezone-aware and timezone-naive datetimes during sorting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --------- Co-authored-by: Claude --- .../utils/maintenance/edge_operations.py | 35 +++++++++++-------- uv.lock | 2 +- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/graphiti_core/utils/maintenance/edge_operations.py b/graphiti_core/utils/maintenance/edge_operations.py index d1b37b4a..890ede35 100644 --- a/graphiti_core/utils/maintenance/edge_operations.py +++ b/graphiti_core/utils/maintenance/edge_operations.py @@ -413,21 +413,26 @@ def resolve_edge_contradictions( invalidated_edges: list[EntityEdge] = [] for edge in invalidation_candidates: # (Edge invalid before new edge becomes valid) or (new edge invalid before edge becomes valid) + edge_invalid_at_utc = ensure_utc(edge.invalid_at) + resolved_edge_valid_at_utc = ensure_utc(resolved_edge.valid_at) + edge_valid_at_utc = ensure_utc(edge.valid_at) + resolved_edge_invalid_at_utc = ensure_utc(resolved_edge.invalid_at) + if ( - edge.invalid_at is not None - and resolved_edge.valid_at is not None - and edge.invalid_at <= resolved_edge.valid_at + edge_invalid_at_utc is not None + and resolved_edge_valid_at_utc is not None + and edge_invalid_at_utc <= resolved_edge_valid_at_utc ) or ( - edge.valid_at is not None - and resolved_edge.invalid_at is not None - and resolved_edge.invalid_at <= edge.valid_at + edge_valid_at_utc is not None + and resolved_edge_invalid_at_utc is not None + and resolved_edge_invalid_at_utc <= edge_valid_at_utc ): continue # New edge invalidates edge elif ( - edge.valid_at is not None - and resolved_edge.valid_at is not None - and edge.valid_at < resolved_edge.valid_at + edge_valid_at_utc is not None + and resolved_edge_valid_at_utc is not None + and edge_valid_at_utc < resolved_edge_valid_at_utc ): edge.invalid_at = resolved_edge.valid_at edge.expired_at = edge.expired_at if edge.expired_at is not None else utc_now() @@ -619,14 +624,14 @@ async def resolve_extracted_edge( # Determine if the new_edge needs to be expired if resolved_edge.expired_at is None: - invalidation_candidates.sort(key=lambda c: (c.valid_at is None, c.valid_at)) + invalidation_candidates.sort(key=lambda c: (c.valid_at is None, ensure_utc(c.valid_at))) for candidate in invalidation_candidates: + candidate_valid_at_utc = ensure_utc(candidate.valid_at) + resolved_edge_valid_at_utc = ensure_utc(resolved_edge.valid_at) if ( - candidate.valid_at - and resolved_edge.valid_at - and candidate.valid_at.tzinfo - and resolved_edge.valid_at.tzinfo - and candidate.valid_at > resolved_edge.valid_at + candidate_valid_at_utc is not None + and resolved_edge_valid_at_utc is not None + and candidate_valid_at_utc > resolved_edge_valid_at_utc ): # Expire new edge since we have information about more recent events resolved_edge.invalid_at = candidate.valid_at diff --git a/uv.lock b/uv.lock index 5c150a85..7ba9bde7 100644 --- a/uv.lock +++ b/uv.lock @@ -783,7 +783,7 @@ wheels = [ [[package]] name = "graphiti-core" -version = "0.22.0rc4" +version = "0.22.0rc5" source = { editable = "." } dependencies = [ { name = "diskcache" },