Skip to content

Commit 07b5ef4

Browse files
authored
fix: treat [0] document references as out of range in AnswerBuilder (#12061)
1 parent 007c66b commit 07b5ef4

3 files changed

Lines changed: 43 additions & 3 deletions

File tree

haystack/components/builders/answer_builder.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,14 @@ def run(
223223
)
224224

225225
for idx in doc_idxs:
226-
try:
227-
doc = documents[idx]
228-
except IndexError:
226+
# An explicit bounds check is needed because references are 1-based: a reference like [0]
227+
# yields idx = -1, which Python would otherwise silently resolve to the last document.
228+
if not 0 <= idx < len(documents):
229229
logger.warning(
230230
"Document index '{index}' referenced in Generator output is out of range. ", index=idx + 1
231231
)
232232
continue
233+
doc = documents[idx]
233234

234235
doc_meta: dict[str, Any] = dict(doc.meta or {})
235236
doc_meta["source_index"] = idx + 1
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
fixes:
3+
- |
4+
AnswerBuilder now treats a ``[0]`` document reference as out of range instead of silently attaching
5+
the last document. References are 1-based, so ``[0]`` produced a negative index that bypassed the
6+
out-of-range guard, marking an unrelated document as ``referenced`` with a wrong ``source_index``.
7+
The same applied to expanded reference ranges starting at 0 (e.g. ``[0-1]``).

test/components/builders/test_answer_builder.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,38 @@ def test_run_with_documents_with_reference_pattern_and_no_match(self, caplog):
186186
assert len(answers[0].documents) == 0
187187
assert "Document index '3' referenced in Generator output is out of range." in caplog.text
188188

189+
def test_run_with_documents_with_zero_reference(self, caplog):
190+
# References are 1-based, so [0] is out of range and must not silently
191+
# resolve to the last document via a negative index.
192+
component = AnswerBuilder(reference_pattern="\\[(\\d+)\\]")
193+
with caplog.at_level(logging.WARNING):
194+
output = component.run(
195+
query="test query",
196+
replies=["Answer: AnswerString[0]"],
197+
meta=[{}],
198+
documents=[Document(content="test doc 1"), Document(content="test doc 2")],
199+
)
200+
answers = output["answers"]
201+
assert len(answers) == 1
202+
assert len(answers[0].documents) == 0
203+
assert "Document index '0' referenced in Generator output is out of range." in caplog.text
204+
205+
def test_run_with_zero_reference_in_expanded_range(self, caplog):
206+
component = AnswerBuilder(reference_pattern="\\[([\\d\\s,-]+)\\]", expand_reference_ranges=True)
207+
with caplog.at_level(logging.WARNING):
208+
output = component.run(
209+
query="test query",
210+
replies=["Answer: AnswerString[0-1]"],
211+
meta=[{}],
212+
documents=[Document(content="test doc 1"), Document(content="test doc 2")],
213+
)
214+
answers = output["answers"]
215+
assert len(answers) == 1
216+
assert len(answers[0].documents) == 1
217+
assert answers[0].documents[0].content == "test doc 1"
218+
assert answers[0].documents[0].meta["referenced"] is True
219+
assert "Document index '0' referenced in Generator output is out of range." in caplog.text
220+
189221
def test_run_with_reference_pattern_set_at_runtime(self):
190222
component = AnswerBuilder(reference_pattern="unused pattern")
191223
output = component.run(

0 commit comments

Comments
 (0)