infiniflow/ragflow · error · ValueError

[Categorize] Message window size cannot be negative

Error message

[Categorize] Message window size cannot be negative

What it means

Raised by CategorizeParam.check (agent/component/categorize.py) when message_history_window_size is not an int (bools are technically int subclasses and would pass isinstance, floats and strings fail) or is negative. The window size controls how many prior conversation messages the categorizer sees; it must be a non-negative integer.

Source

Thrown at agent/component/categorize.py:44

from common.connection_utils import timeout
from rag.llm.chat_model import ERROR_PREFIX


class CategorizeParam(LLMParam):
    """
    Define the categorize component parameters.
    """

    def __init__(self):
        super().__init__()
        self.category_description = {}
        self.query = "sys.query"
        self.message_history_window_size = 1
        self.update_prompt()

    def check(self):
        if not isinstance(self.message_history_window_size, int) or self.message_history_window_size < 0:
            raise ValueError("[Categorize] Message window size cannot be negative")
        self.check_empty(self.category_description, "[Categorize] Category examples")
        for k, v in self.category_description.items():
            if not k:
                raise ValueError("[Categorize] Category name can not be empty!")
            if not v.get("to"):
                raise ValueError(f"[Categorize] 'To' of category {k} can not be empty!")

    def get_input_form(self) -> dict[str, dict]:
        return {"query": {"type": "line", "name": "Query"}}

    def update_prompt(self):
        cate_lines = []
        for c, desc in self.category_description.items():
            for line in desc.get("examples", []):
                if not line:
                    continue
                cate_lines.append('USER: "' + re.sub(r"\n", "    ", line, flags=re.DOTALL) + '" → ' + c)

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Set message_history_window_size to a non-negative integer such as 1 (the default) or larger, e.g. 5
  2. Coerce programmatic values with int(value) and clamp: max(0, int(value))
  3. Do not use -1 for unlimited — pick an explicit positive window size

Example fix

# before
"message_history_window_size": -1

# after
"message_history_window_size": 5
Defensive patterns

Strategy: validation

Validate before calling

window_size = config.get('message_history_window_size', 1)
if isinstance(window_size, bool) or not isinstance(window_size, int) or window_size < 0:
    window_size = max(0, int(window_size))  # or reject explicitly
param.message_history_window_size = window_size

Type guard

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

Try / catch

try:
    param.check()
except ValueError as e:
    if 'Message window size' in str(e):
        param.message_history_window_size = 1  # safe default
    else:
        raise

Prevention

When it happens

Trigger: Setting the Categorize component's message_history_window_size to -1 (meaning 'unlimited' in some other tools), 1.0 (float from JSON), or "3" (string) in the canvas; also programmatically building the component with a computed float value. Fires during parameter validation on save/run.

Common situations: Users assuming negative means unlimited; frontend numeric inputs yielding floats; API-driven canvas generation writing strings; migrating configs from systems with different semantics.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/f04655935292853e. Report an issue: GitHub.