deepset-ai/haystack · error · ValueError
top_k must not be negative.
Error message
top_k must not be negative.
What it means
DocumentJoiner.run raises ValueError when the runtime top_k argument is negative. top_k truncates the joined document list; negative values are rejected before slicing. (Runtime top_k may be 0, unlike the init check which requires > 0.)
Source
Thrown at haystack/components/joiners/document_joiner.py:174
:raises ValueError:
If `top_k` is negative.
"""
documents = list(documents)
output_documents = self.join_mode_function(documents)
if self.sort_by_score:
output_documents = sorted(
output_documents, key=lambda doc: doc.score if doc.score is not None else -inf, reverse=True
)
if any(doc.score is None for doc in output_documents):
logger.info(
"Some of the Documents DocumentJoiner got have score=None. It was configured to sort Documents by "
"score, so those with score=None were sorted as if they had a score of -infinity."
)
if top_k is not None:
if top_k < 0:
raise ValueError("top_k must not be negative.")
output_documents = output_documents[:top_k]
elif self.top_k is not None:
output_documents = output_documents[: self.top_k]
return {"documents": output_documents}
@staticmethod
def _concatenate(document_lists: list[list[Document]]) -> list[Document]:
"""
Concatenate multiple lists of Documents and return only the Document with the highest score for duplicates.
"""
output = []
docs_per_id = defaultdict(list)
for doc in itertools.chain.from_iterable(document_lists):
docs_per_id[doc.id].append(doc)
for docs in docs_per_id.values():
doc_with_best_score = max(docs, key=lambda doc: doc.score if doc.score is not None else -inf)
output.append(doc_with_best_score)View on GitHub (pinned to e318778c9b)
Solutions
- Pass top_k=None in run() to use the init-time top_k or keep all documents.
- Ensure the runtime top_k is >= 0.
- Clamp with max(0, top_k) before calling run().
Example fix
// before joiner.run(documents=docs, top_k=-1) // after joiner.run(documents=docs, top_k=None) # or a non-negative int
Defensive patterns
Strategy: validation
Validate before calling
if run_top_k is not None and run_top_k < 0:
raise ValueError(f"runtime top_k must be >= 0 or None, got {run_top_k}")
joiner.run(documents=docs, top_k=run_top_k) Type guard
def is_valid_run_top_k(v: int | None) -> bool:
return v is None or (isinstance(v, int) and v >= 0) Try / catch
try:
out = joiner.run(documents=docs, top_k=k)
except ValueError as e:
logger.warning("bad runtime top_k: %s", e)
out = joiner.run(documents=docs, top_k=None) Prevention
- Use None, not -1, to mean 'no limit' at runtime
- Clamp values from external input: max(0, k)
- Distinguish the init rule (>0) from the runtime rule (>=0)
When it happens
Trigger: document_joiner.run(documents=..., top_k=-1) or any negative int at runtime.
Common situations: Using -1 as a 'no limit' sentinel; deriving top_k from user input or config without validation; confusing the stricter init rule (must be > 0) with the looser runtime rule (>= 0).
Understand the failure class
Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.
Related errors
- 'response_fn' must return an assistant ChatMessage, got '{re
- Cannot stream multiple responses, please set n=1.
- A `ChatMessage` must contain at least one `TextContent`, `To
- top_k must be greater than 0.
- top_k must not be negative.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/1c5c28be969a0619.
Report an issue: GitHub.