deepset-ai/haystack · error

`context_window` must be a positive number of tokens, got {c

Error message

`context_window` must be a positive number of tokens, got {context_window}.

What it means

This ValueError comes from a compaction hook's __init__ (haystack/hooks/compaction/hooks.py:92). The hook needs to know the model's context window size to decide when to compact; it refuses to run with a nonsensical size. A context_window of 0 or negative would make trigger/threshold math meaningless.

Source

Thrown at haystack/hooks/compaction/hooks.py:92

        token_counter: TokenCounter | None = None,
    ) -> None:
        """
        Initialize the hook with a compactor and the window it has to fit in.

        :param compactor: The `Compactor` that rewrites the conversation.
        :param context_window: The model's context window in tokens. Everything else is a fraction of this, so moving to
            a different model means changing only this number.
        :param compact_at: The fraction of the window at which compaction starts. Leave room above it for the reply and
            the tool results it triggers, which land on top of what was measured.
        :param compact_to: The fraction of the window compaction aims to bring the conversation down to. Lower means
            compacting less often but losing more each time.
        :param token_counter: The `TokenCounter` used to size the messages the chat generator has not reported on yet.
            Defaults to `ApproximateTokenCounter`, which needs no extra dependency.
        :raises ValueError: If `context_window` is not positive, or the fractions are not
            `0 < compact_to < compact_at <= 1`.
        """
        if context_window < 1:
            raise ValueError(f"`context_window` must be a positive number of tokens, got {context_window}.")
        if not 0 < compact_to < compact_at <= 1:
            raise ValueError(
                f"`compact_at` and `compact_to` must satisfy 0 < compact_to < compact_at <= 1, got "
                f"compact_at={compact_at} and compact_to={compact_to}. A target at or above the trigger would leave "
                f"the conversation over the trigger after compacting, so it would be attempted again every step."
            )
        self.compactor = compactor
        self.context_window = context_window
        self.compact_at = compact_at
        self.compact_to = compact_to
        self.token_counter = token_counter or ApproximateTokenCounter()

    def run(self, state: State) -> None:
        """
        Compact `state.data["messages"]` if the conversation fills too much of the window.

        :param state: The Agent's live `State`. Read to decide whether to compact, and rewritten in place when the
            compactor returns a compacted conversation.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Set context_window to the model's actual context size in tokens, e.g. context_window=128000.
  2. If it comes from config, assert it is a positive int before constructing: value = int(cfg); assert value > 0.
  3. Look up the correct value in the model provider's docs if unsure.

Example fix

// before
hook = CompactionHook(context_window=0)
// after
hook = CompactionHook(context_window=128_000)
Defensive patterns

Strategy: validation

Validate before calling

def validate_context_window(context_window):
    if not isinstance(context_window, int) or context_window < 1:
        raise ValueError(f"context_window must be a positive int, got {context_window!r}")
# call before constructing the hook

Type guard

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

Try / catch

try:
    hook = CompactionHook(context_window=cw)
except ValueError as e:
    logger.error("bad context_window: %s", e)
    hook = CompactionHook(context_window=128_000)

Prevention

When it happens

Trigger: Passing context_window=0, a negative number, or an unset/None-ish value coerced to 0 when constructing the compaction hook class.

Common situations: Hardcoding a placeholder of 0 intending to fill it later; reading the context window from an empty config/env var and getting 0; copy-pasting a template constructor call without setting the value.

Related errors


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