run-llama/llama_index · error · ValueError

Token limit must be set and greater than 0.

Error message

Token limit must be set and greater than 0.

What it means

ChatMemoryBuffer enforces a positive token_limit via a pydantic model_validator: values default to -1 when absent, and anything below 1 (unset, 0, negative) fails with this ValueError. The limit is essential because the buffer's whole job is evicting messages once the token count exceeds it.

Source

Thrown at llama-index-core/llama_index/core/memory/chat_memory_buffer.py:43

    token_limit: int
    tokenizer_fn: Callable[[str], List] = Field(
        default_factory=get_tokenizer,
        exclude=True,
    )

    @classmethod
    def class_name(cls) -> str:
        """Get class name."""
        return "ChatMemoryBuffer"

    @model_validator(mode="before")
    @classmethod
    def validate_memory(cls, values: dict) -> dict:
        # Validate token limit
        token_limit = values.get("token_limit", -1)
        if token_limit < 1:
            raise ValueError("Token limit must be set and greater than 0.")

        # Validate tokenizer -- this avoids errors when loading from json/dict
        tokenizer_fn = values.get("tokenizer_fn")
        if tokenizer_fn is None:
            values["tokenizer_fn"] = get_tokenizer()

        return values

    @classmethod
    def from_defaults(
        cls,
        chat_history: Optional[List[ChatMessage]] = None,
        llm: Optional[LLM] = None,
        chat_store: Optional[BaseChatStore] = None,
        chat_store_key: str = DEFAULT_CHAT_STORE_KEY,
        token_limit: Optional[int] = None,
        tokenizer_fn: Optional[Callable[[str], List]] = None,
        **kwargs: Any,

View on GitHub (pinned to afd0fef371)

Solutions

  1. Use ChatMemoryBuffer.from_defaults(llm=llm) — it derives token_limit from the LLM context window or DEFAULT_TOKEN_LIMIT.
  2. Pass an explicit positive value: ChatMemoryBuffer(token_limit=3000).
  3. When loading from a dict, ensure token_limit survived serialization; re-add it before constructing.

Example fix

# before
memory = ChatMemoryBuffer()  # ValueError: unset token_limit
# after
memory = ChatMemoryBuffer.from_defaults(llm=llm)
# or
memory = ChatMemoryBuffer(token_limit=3000)
Defensive patterns

Strategy: validation

Validate before calling

def is_valid_memory_config(token_limit) -> bool:
    return isinstance(token_limit, int) and token_limit >= 1

assert is_valid_memory_config(kwargs.get("token_limit", -1)), "token_limit must be a positive int"

Type guard

def has_valid_token_limit(memory_dict: dict) -> bool:
    tl = memory_dict.get("token_limit", -1)
    return isinstance(tl, int) and tl >= 1

Try / catch

try:
    memory = ChatMemoryBuffer(**data)
except ValueError as e:
    if "Token limit" in str(e):
        data["token_limit"] = 3000  # sensible default
        memory = ChatMemoryBuffer(**data)
    else:
        raise

Prevention

When it happens

Trigger: Constructing ChatMemoryBuffer() directly (not via from_defaults) without token_limit; passing token_limit=0 or a negative number; deserializing a dict/JSON that lacks the token_limit field.

Common situations: Copying examples that use ChatMemoryBuffer.from_defaults but switching to the raw constructor; persisting memory to JSON with a serializer that drops defaults; passing token_limit=None explicitly.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/cee4ac74b48a1a38. Report an issue: GitHub.