deepset-ai/haystack · error · ValueError

top_k must be > 0, but got {top_k}

Error message

top_k must be > 0, but got {top_k}

What it means

LostInTheMiddleRanker's __init__ rejects a top_k that is an int <= 0. top_k caps how many documents the ranker returns, so zero or negative values cannot produce a valid result set. Raised as ValueError at construction time.

Source

Thrown at haystack/components/rankers/lost_in_the_middle.py:57

    def __init__(self, word_count_threshold: int | None = None, top_k: int | None = None) -> None:
        """
        Initialize the LostInTheMiddleRanker.

        If 'word_count_threshold' is specified, this ranker includes all documents up until the point where adding
        another document would exceed the 'word_count_threshold'. The last document that causes the threshold to
        be breached will be included in the resulting list of documents, but all subsequent documents will be
        discarded.

        :param word_count_threshold: The maximum total number of words across all documents selected by the ranker.
        :param top_k: The maximum number of documents to return.
        """
        if isinstance(word_count_threshold, int) and word_count_threshold <= 0:
            raise ValueError(
                f"Invalid value for word_count_threshold: {word_count_threshold}. word_count_threshold must be > 0."
            )
        if isinstance(top_k, int) and top_k <= 0:
            raise ValueError(f"top_k must be > 0, but got {top_k}")

        self.word_count_threshold = word_count_threshold
        self.top_k = top_k

    @component.output_types(documents=list[Document])
    def run(
        self, documents: list[Document], top_k: int | None = None, word_count_threshold: int | None = None
    ) -> dict[str, list[Document]]:
        """
        Reranks documents based on the "lost in the middle" order.

        Before ranking, documents are deduplicated by their id, retaining only the document with the highest score
        if a score is present.

        :param documents: List of Documents to reorder.
        :param top_k: The maximum number of documents to return.
        :param word_count_threshold: The maximum total number of words across all documents selected by the ranker.
        :returns:

View on GitHub (pinned to e318778c9b)

Solutions

  1. Pass a positive integer for top_k, e.g. LostInTheMiddleRanker(top_k=10).
  2. Guard the source variable: only construct the ranker when top_k > 0.
  3. Use the default top_k by omitting the parameter if no explicit limit is needed.

Example fix

// before
ranker = LostInTheMiddleRanker(top_k=0)
// after
ranker = LostInTheMiddleRanker(top_k=10)
Defensive patterns

Strategy: validation

Validate before calling

def ensure_valid_top_k(v):
    if isinstance(v, int) and v <= 0:
        raise ValueError(f"top_k must be > 0, got {v}")
    return v

Type guard

def is_positive_int(v) -> bool:
    return isinstance(v, int) and v > 0

Try / catch

try:
    ranker = LostInTheMiddleRanker(top_k=k)
except ValueError:
    ranker = LostInTheMiddleRanker(top_k=10)  # safe default

Prevention

When it happens

Trigger: Calling LostInTheMiddleRanker(top_k=0) or a negative int; the check only applies when the value is an int instance (None or floats bypass it).

Common situations: top_k computed from a variable (e.g. user input or len() of an empty list) that is 0; config templates with 0 placeholders; off-by-one in subtraction logic.

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/77125e6712a7f22e. Report an issue: GitHub.