Skip to content

fix: date filter parameters collide across OR clauses#1596

Open
totto wants to merge 1 commit into
getzep:mainfrom
totto:fix/date-filter-param-collision
Open

fix: date filter parameters collide across OR clauses#1596
totto wants to merge 1 commit into
getzep:mainfrom
totto:fix/date-filter-param-collision

Conversation

@totto

@totto totto commented Jun 17, 2026

Copy link
Copy Markdown

What

In build_edge_search_filter_query(), date filter parameters are keyed by only the inner-loop index j, not by the outer OR-clause index i:

for i, or_list in enumerate(filters.valid_at):
    for j, date_filter in enumerate(or_list):
        filter_params['valid_at_' + str(j)] = date_filter.date  # ← bug

When filters.valid_at has more than one OR clause, each clause resets j to 0. OR clause 1 overwrites OR clause 0's parameter values. The Cypher query then uses the wrong date values for all but the last OR clause.

Why it matters

Any temporal filter with multiple OR conditions silently applies the last clause's dates to all clauses, producing incorrect query results without any error.

The same bug exists in all four date fields: valid_at, invalid_at, created_at, expired_at.

Fix

Key by both i (OR-clause) and j (AND-condition within clause):

filter_params[f'valid_at_{i}_{j}'] = date_filter.date
# query uses: f'$valid_at_{i}_{j}'

Applied to all four date fields.

Reproducer

from datetime import datetime
from graphiti_core.search.search_filters import EdgeSearchFilters, DateFilter
from graphiti_core.search.search_filters import ComparisonOperator, build_edge_search_filter_query

d1 = datetime(2024, 1, 1)
d2 = datetime(2025, 1, 1)

filters = EdgeSearchFilters(
    valid_at=[
        [DateFilter(date=d1, comparison_operator=ComparisonOperator.gt)],
        [DateFilter(date=d2, comparison_operator=ComparisonOperator.lt)],
    ]
)
_, params = build_edge_search_filter_query(filters, "neo4j")
# Before fix: params == {'valid_at_0': d2}   ← d1 lost
# After fix:  params == {'valid_at_0_0': d1, 'valid_at_1_0': d2}  ✓

When a date filter had multiple OR clauses (filters.valid_at is a list of
lists), each OR clause's inner-loop counter j reset to 0. Parameters were
keyed as 'valid_at_0', 'valid_at_1', etc., so each OR clause overwrote the
previous clause's parameter values. The Cypher query then used the wrong
dates for all but the last OR clause.

Fix: key by f'{field}_{i}_{j}' (outer OR index i + inner AND index j) for
all four date fields: valid_at, invalid_at, created_at, expired_at.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zep-cla-assistant

Copy link
Copy Markdown
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. For privacy information, see our Privacy Notice. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA behalf on myself, e-mail: example@example.com

or

I have read the CLA Document and I hereby sign the CLA behalf of my company, e-mail: example@example.com

Signature is valid for 6 months.


This bot will be retriggered when the Contributor License Agreement comment has been provided. Posted by the CLA Assistant Lite bot.

@totto

totto commented Jun 19, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA behalf on myself, e-mail: totto@exoreaction.com

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