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

MetaFieldRanker._validate_params (called from both __init__ and run) rejects a top_k that is not None and <= 0. top_k caps how many documents the ranker returns; None means 'use the init value'. Raised as ValueError.

Source

Thrown at haystack/components/rankers/meta_field.py:121

            ranking_mode=self.ranking_mode,
            sort_order=self.sort_order,
            missing_meta=self.missing_meta,
            meta_value_type=meta_value_type,
        )
        self.meta_value_type = meta_value_type

    def _validate_params(
        self,
        *,
        weight: float,
        top_k: int | None,
        ranking_mode: Literal["reciprocal_rank_fusion", "linear_score"],
        sort_order: Literal["ascending", "descending"],
        missing_meta: Literal["drop", "top", "bottom"],
        meta_value_type: Literal["float", "int", "date"] | None,
    ) -> None:
        if top_k is not None and top_k <= 0:
            raise ValueError(f"top_k must be > 0, but got {top_k}")

        if weight < 0 or weight > 1:
            raise ValueError(
                f"Parameter <weight> must be in range [0,1] but is currently set to '{weight}'.\n'0' disables sorting "
                "by a meta field, '0.5' assigns equal weight to the previous relevance scores and the meta field, and "
                "'1' ranks by the meta field only.\nChange the <weight> parameter to a value in range 0 to 1 when "
                "initializing the MetaFieldRanker."
            )

        if ranking_mode not in ["reciprocal_rank_fusion", "linear_score"]:
            raise ValueError(
                "The value of parameter <ranking_mode> must be 'reciprocal_rank_fusion' or 'linear_score', but is "
                f"currently set to '{ranking_mode}'.\nChange the <ranking_mode> value to 'reciprocal_rank_fusion' or "
                "'linear_score' when initializing the MetaFieldRanker."
            )

        if sort_order not in ["ascending", "descending"]:
            raise ValueError(

View on GitHub (pinned to e318778c9b)

Solutions

  1. Pass a positive integer for top_k or None to defer to the constructor value.
  2. Clamp at the call site: top_k = max(1, top_k) if top_k is not None else None.
  3. Fix the config source so a valid default (e.g. 10) is used when the key is missing.

Example fix

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

Strategy: validation

Validate before calling

if top_k is not None and top_k <= 0:
    raise ValueError(f"top_k must be > 0, got {top_k}")

Type guard

def is_valid_top_k(v) -> bool:
    return v is None or (isinstance(v, int) and v > 0)

Try / catch

try:
    ranker = MetaFieldRanker(top_k=top_k, weight=weight, ranking_mode=mode, sort_order=order, missing_meta=mm)
except ValueError as e:
    logger.error("Invalid MetaFieldRanker params: %s", e)
    ranker = MetaFieldRanker()

Prevention

When it happens

Trigger: MetaFieldRanker(top_k=0), MetaFieldRanker(top_k=-5), or ranker.run(documents=..., top_k=0) at runtime; validation runs on every init and run call.

Common situations: Reading top_k from config/env where a default of 0 was left; passing `results_count` from an upstream component that returned zero results; run-time overrides built dynamically.

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/3c364a4188051940. Report an issue: GitHub.