{"record":{"id":"cfcf9ba7ef2e645c","repo":"deepset-ai/haystack","slug":"min-keep-steps-must-be-at-least-0-got-min-keep-cfcf9b","errorCode":null,"errorMessage":"`min_keep_steps` must be at least 0, got {min_keep_steps}.","messagePattern":"`min_keep_steps` must be at least 0, got (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"haystack/hooks/compaction/summarization.py","lineNumber":231,"sourceCode":"\n        :param chat_generator: The Chat Generator used to write summaries.\n        :param min_keep_steps: The fewest complete recent Agent steps to keep, even when they exceed the target.\n        :param approximate_summary_tokens: About how long you expect a summary to come out. This is an estimate used\n            for planning, not a limit imposed on the model. The compactor uses it to work out how much of the\n            conversation to summarize. A higher value causes the compactor to summarize more of the conversation per\n            round, so the result is likelier to land under the target, at the cost of giving up more of the\n            conversation. A lower value summarizes less per round and keeps more, but may leave the result above the\n            target.\n        :param summary_instruction: The prompt instructions for how to summarize a portion of the conversation.\n            The default instructions ask for a summary with fixed sections covering the objective, decisions and\n            constraints, completed work, exact identifiers, and unresolved work.\n        :param raise_on_failure: Whether to raise an exception if the chat generator fails or returns a summary that\n            does not shrink the conversation. By default the failure is logged and any successful partial compaction\n            is returned.\n        :raises ValueError: If `min_keep_steps` is negative or `approximate_summary_tokens` is not positive.\n        \"\"\"\n        if min_keep_steps < 0:\n            raise ValueError(f\"`min_keep_steps` must be at least 0, got {min_keep_steps}.\")\n        if approximate_summary_tokens < 1:\n            raise ValueError(\n                f\"`approximate_summary_tokens` must be a positive number of tokens, got {approximate_summary_tokens}.\"\n            )\n        self.chat_generator = chat_generator\n        self.min_keep_steps = min_keep_steps\n        self.approximate_summary_tokens = approximate_summary_tokens\n        self.summary_instruction = summary_instruction\n        self.raise_on_failure = raise_on_failure\n\n    def compact(\n        self, messages: list[ChatMessage], target_tokens: int, token_counter: TokenCounter\n    ) -> list[ChatMessage] | None:\n        \"\"\"\n        Return a progressively summarized conversation, or None when no useful reduction is possible.\n\n        :param messages: The conversation to compact, ordered oldest to newest.\n        :param target_tokens: The token budget the compacted messages should aim to fit.","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/hooks/compaction/summarization.py#L213-L249","documentation":"SummarizationCompactor validates min_keep_steps in __init__ (haystack/hooks/compaction/summarization.py:231) and raises ValueError for negative values. min_keep_steps guarantees the most recent steps are never summarized away; negative values are invalid.","triggerScenarios":"Constructing SummarizationCompactor with min_keep_steps < 0, often from a computed or config-supplied value.","commonSituations":"Arithmetic on a keep-count that underflows below zero; typos like min_keep_steps=-2 in example configs; changing defaults by subtraction.","solutions":["Pass min_keep_steps >= 0.","Clamp: min_keep_steps = max(0, value) before constructing.","Correct the upstream config/env value."],"exampleFix":"// before\ncompactor = SummarizationCompactor(chat_generator=g, min_keep_steps=-1)\n// after\ncompactor = SummarizationCompactor(chat_generator=g, min_keep_steps=2)","handlingStrategy":"validation","validationCode":"def validate_min_keep_steps(v):\n    if not isinstance(v, int) or v < 0:\n        raise ValueError(f\"min_keep_steps must be >= 0, got {v!r}\")\nvalidate_min_keep_steps(cfg.get(\"min_keep_steps\", 2))","typeGuard":"def is_non_negative_int(v) -> bool:\n    return isinstance(v, int) and not isinstance(v, bool) and v >= 0","tryCatchPattern":"try:\n    compactor = SummarizationCompactor(chat_generator=gen, min_keep_steps=n)\nexcept ValueError as e:\n    logger.error(\"bad min_keep_steps: %s\", e)\n    compactor = SummarizationCompactor(chat_generator=gen, min_keep_steps=2)","preventionTips":["Clamp with max(0, value) after any arithmetic","Provide sane config defaults (e.g. 2)","Validate all compactor params together in one pre-check"],"tags":["validation","constructor","config","compaction"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}