From b5d35610664b8bc3e68709e0e62a109a0eb21519 Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Mon, 2 Nov 2026 12:19:13 +0100 Subject: [PATCH] fix(python): reject empty multivector reranker input Reject empty multivector result lists with `ValueError` before accessing the first result, matching the existing RRF and MRR behavior. Non-empty lists, zero-row tables, and both deduplication modes retain their existing behavior. Regression coverage exercises the shared base reranker through both deduplication settings. The exact-head Python suite passed with 3021 passed, 126 skipped, and 70 deselected. --- python/python/lancedb/rerankers/base.py | 2 ++ python/python/tests/test_rerankers.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/python/python/lancedb/rerankers/base.py b/python/python/lancedb/rerankers/base.py index e1bc7f0dd..966f23eeb 100644 --- a/python/python/lancedb/rerankers/base.py +++ b/python/python/lancedb/rerankers/base.py @@ -189,6 +189,8 @@ class Reranker(ABC): vector_results = ( [vector_results] if not isinstance(vector_results, list) else vector_results ) + if not vector_results: + raise ValueError("vector_results must not be empty") # Make sure all elements are of the same type if not all(isinstance(v, type(vector_results[0])) for v in vector_results): diff --git a/python/python/tests/test_rerankers.py b/python/python/tests/test_rerankers.py index 610f533f5..eb7705f80 100644 --- a/python/python/tests/test_rerankers.py +++ b/python/python/tests/test_rerankers.py @@ -28,6 +28,7 @@ from lancedb.rerankers import ( WatsonxReranker, ) from lancedb.table import LanceTable +from lancedb.rerankers.base import Reranker def get_test_table(tmp_path): @@ -358,6 +359,19 @@ def test_mrr_reranker(tmp_path): assert len(result_deduped) == len(result) +@pytest.mark.parametrize("deduplicate", [False, True]) +def test_base_reranker_multivector_empty_input(deduplicate): + class VectorReranker(Reranker): + def rerank_hybrid(self, query, vector_results, fts_results): + raise AssertionError("should not rerank") + + def rerank_vector(self, query, vector_results): + raise AssertionError("should not rerank") + + with pytest.raises(ValueError, match="vector_results must not be empty"): + VectorReranker().rerank_multivector([], None, deduplicate=deduplicate) + + def test_mrr_reranker_empty_input(): reranker = MRRReranker() with pytest.raises(ValueError, match="must not be empty"):