Skip to content

[MOD-12647] fix: handle the case in Coordinator when SCORE is sent alone without extra fields.#7492

Merged
JoanFM merged 10 commits intomasterfrom
joan-mod-12647
Nov 27, 2025
Merged

[MOD-12647] fix: handle the case in Coordinator when SCORE is sent alone without extra fields.#7492
JoanFM merged 10 commits intomasterfrom
joan-mod-12647

Conversation

@JoanFM
Copy link
Collaborator

@JoanFM JoanFM commented Nov 24, 2025

Describe the changes in the pull request

In case of Loading Document fails because key is expired or trimmed, Hybrid Result serializer is sending scores even when documents are not loaded.

This breaks the invairants in the Coordinator leading to a potential crash.


Note

Gracefully handle RESP3 rows with scores but no fields in the coordinator, update hybrid response parsing for RESP3, and add FT.HYBRID expiration tests for RESP2/RESP3.

  • Coordinator (src/coord/rpnet.c):
    • Handle cases where RESP3 results may include score without extra_attributes (e.g., expired docs): add has_fields guard and skip field writes when absent.
    • Relax/adjust assertions for RESP2/RESP3 to validate fields only when present; keep score type checks.
  • Tests:
    • Update get_results_from_hybrid_response to parse RESP3 dict replies and return results with total_results.
    • Add FT.HYBRID expiration tests (test_expire_ft_hybrid_resp2/resp3) verifying only non-expired docs are returned with expected attributes.

Written by Cursor Bugbot for commit 451305b. This will update automatically on new commits. Configure here.

@JoanFM JoanFM changed the title fix: Do not send SCORE without extra fields for Hybrid Response [MOD-12647] fix: Do not send SCORE without extra fields for Hybrid Search Response Nov 24, 2025
@JoanFM JoanFM requested a review from kei-nan November 24, 2025 16:39
@codecov
Copy link

codecov bot commented Nov 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.98%. Comparing base (0d50df3) to head (451305b).
⚠️ Report is 19 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7492      +/-   ##
==========================================
- Coverage   85.05%   84.98%   -0.07%     
==========================================
  Files         348      349       +1     
  Lines       53773    53879     +106     
  Branches    14353    14384      +31     
==========================================
+ Hits        45734    45787      +53     
- Misses       7843     7896      +53     
  Partials      196      196              
Flag Coverage Δ
flow 85.14% <100.00%> (+0.07%) ⬆️
unit 52.38% <0.00%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

env.assertEqual(res, [1, ['t', 'arr'], ['t', 'bar']])


def test_expire_ft_hybrid(env):
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the fix is relevant for RESP3, shouldn't the test also run using RESP3?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

isnt it the default here? how should I enforce this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added tests for both

@JoanFM JoanFM requested review from kei-nan and oshadmi November 26, 2025 11:54
results[key] = result
total_results = response.get('total_results', 0)
return results, total_results

Copy link

Choose a reason for hiding this comment

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

Bug: Breaking API change in helper function

The get_results_from_hybrid_response function signature changed from returning a single dict to returning a tuple (results, total_results). This breaks all existing callers in other test files like test_default_scorer.py that aren't updated in this commit, causing them to fail when they try to use the return value as a dict instead of unpacking the tuple.

Fix in Cursor Fix in Web

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the signature did not change, it returns results, total_results in both cases.

@JoanFM JoanFM requested a review from oshadmi November 26, 2025 14:45
@JoanFM JoanFM enabled auto-merge November 26, 2025 14:48
@JoanFM JoanFM added this pull request to the merge queue Nov 27, 2025
Merged via the queue into master with commit b916f07 Nov 27, 2025
32 checks passed
@JoanFM JoanFM deleted the joan-mod-12647 branch November 27, 2025 13:30
@redisearch-backport-pull-request
Copy link
Contributor

Backport failed for 2.10, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin 2.10
git worktree add -d .worktree/backport-7492-to-2.10 origin/2.10
cd .worktree/backport-7492-to-2.10
git switch --create backport-7492-to-2.10
git cherry-pick -x b916f078190664ddf8d51d521f79caa13e3fc1bf

@redisearch-backport-pull-request
Copy link
Contributor

Backport failed for 8.2, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin 8.2
git worktree add -d .worktree/backport-7492-to-8.2 origin/8.2
cd .worktree/backport-7492-to-8.2
git switch --create backport-7492-to-8.2
git cherry-pick -x b916f078190664ddf8d51d521f79caa13e3fc1bf

redisearch-backport-pull-request bot pushed a commit that referenced this pull request Nov 27, 2025
…one without extra fields. (#7492)

* fix: Do not send score alone if Expired flag is set

* test: add test_expire_ft_hybrid

* improve test

* do not send NULL, simply avoid serialize result if expired

* improving test

* handle more complete hybrid expire test

* small change in test

* revert changes in hybrid exec

* remove assertion that cannot be guaranteed, and handle no extra_attributes in response from shard

* handle both resp protocols

(cherry picked from commit b916f07)
@redisearch-backport-pull-request
Copy link
Contributor

JoanFM added a commit that referenced this pull request Nov 27, 2025
…one without extra fields. (#7492)

* fix: Do not send score alone if Expired flag is set

* test: add test_expire_ft_hybrid

* improve test

* do not send NULL, simply avoid serialize result if expired

* improving test

* handle more complete hybrid expire test

* small change in test

* revert changes in hybrid exec

* remove assertion that cannot be guaranteed, and handle no extra_attributes in response from shard

* handle both resp protocols

(cherry picked from commit b916f07)
JoanFM added a commit that referenced this pull request Nov 27, 2025
…one without extra fields. (#7492)

* fix: Do not send score alone if Expired flag is set

* test: add test_expire_ft_hybrid

* improve test

* do not send NULL, simply avoid serialize result if expired

* improving test

* handle more complete hybrid expire test

* small change in test

* revert changes in hybrid exec

* remove assertion that cannot be guaranteed, and handle no extra_attributes in response from shard

* handle both resp protocols

(cherry picked from commit b916f07)
github-merge-queue bot pushed a commit that referenced this pull request Nov 27, 2025
…ent alone without extra fields. (#7553)

[MOD-12647] fix: handle the case in Coordinator when SCORE is sent alone without extra fields. (#7492)

* fix: Do not send score alone if Expired flag is set

* test: add test_expire_ft_hybrid

* improve test

* do not send NULL, simply avoid serialize result if expired

* improving test

* handle more complete hybrid expire test

* small change in test

* revert changes in hybrid exec

* remove assertion that cannot be guaranteed, and handle no extra_attributes in response from shard

* handle both resp protocols

(cherry picked from commit b916f07)

Co-authored-by: Joan Fontanals <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Dec 2, 2025
…ent alone without extra fields. (#7554)

* [MOD-12647] fix: handle the case in Coordinator when SCORE is sent alone without extra fields. (#7492)

* fix: Do not send score alone if Expired flag is set

* test: add test_expire_ft_hybrid

* improve test

* do not send NULL, simply avoid serialize result if expired

* improving test

* handle more complete hybrid expire test

* small change in test

* revert changes in hybrid exec

* remove assertion that cannot be guaranteed, and handle no extra_attributes in response from shard

* handle both resp protocols

(cherry picked from commit b916f07)

* small refactor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants