deepset-ai/haystack · error · ValueError

top_k must be greater than 0.

Error message

top_k must be greater than 0.

What it means

AnswerJoiner validates top_k at construction: if it is set (not None) it must be > 0, otherwise the joiner would produce an empty/invalid selection of answers. haystack raises ValueError immediately in __init__.

Source

Thrown at haystack/components/joiners/answer_joiner.py:106

        self, join_mode: str | JoinMode = JoinMode.CONCATENATE, top_k: int | None = None, sort_by_score: bool = False
    ) -> None:
        """
        Creates an AnswerJoiner component.

        :param join_mode:
            Specifies the join mode to use. Available modes:
            - `concatenate`: Concatenates multiple lists of Answers into a single list.
        :param top_k:
            The maximum number of Answers to return. Must be `None` or greater than 0.
        :param sort_by_score:
            If `True`, sorts the answers by score in descending order.
            If an answer has no score, it is handled as if its score is -infinity.

        :raises ValueError:
            If `top_k` is not `None` and is less than or equal to 0.
        """
        if top_k is not None and top_k <= 0:
            raise ValueError("top_k must be greater than 0.")
        if isinstance(join_mode, str):
            join_mode = JoinMode.from_str(join_mode)
        join_mode_functions: dict[JoinMode, Callable[[list[list[AnswerType]]], list[AnswerType]]] = {
            JoinMode.CONCATENATE: self._concatenate
        }
        self.join_mode_function: Callable[[list[list[AnswerType]]], list[AnswerType]] = join_mode_functions[join_mode]
        self.join_mode = join_mode
        self.top_k = top_k
        self.sort_by_score = sort_by_score

    @component.output_types(answers=list[AnswerType])
    def run(self, answers: Variadic[list[AnswerType]], top_k: int | None = None) -> dict[str, Any]:
        """
        Joins multiple lists of Answers into a single list depending on the `join_mode` parameter.

        :param answers:
            Nested list of Answers to be merged.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Pass top_k=None to keep all answers instead of 0
  2. Use a positive integer for top_k
  3. Clamp computed values: top_k = max(1, top_k) when top_k is not None

Example fix

// before
joiner = AnswerJoiner(top_k=0)
// after
joiner = AnswerJoiner(top_k=None)  # or a positive int
Defensive patterns

Strategy: validation

Validate before calling

if top_k is not None and top_k <= 0:
    top_k = None  # or raise, depending on intent

Try / catch

try:
    joiner = AnswerJoiner(top_k=cfg_top_k)
except ValueError as e:
    if "top_k" in str(e):
        joiner = AnswerJoiner(top_k=None)

Prevention

When it happens

Trigger: AnswerJoiner(top_k=0) or AnswerJoiner(top_k=-5) — commonly from a computed or YAML-config-driven value that resolved to 0 or negative.

Common situations: top_k read from env/config where a sentinel 0 means 'unlimited'; arithmetic producing 0 (e.g. int division); forgetting that None means 'keep all' but 0 is invalid.

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


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/15b90e4abdc6ddc7. Report an issue: GitHub.