microsoft/autogen · error · ValueError

token_limit must be greater than 0.

Error message

token_limit must be greater than 0.

What it means

TokenLimitedChatCompletionContext trims history to fit a token budget; token_limit is optional (None means 'use whatever the model client's remaining_tokens allows'), but if you pass an explicit limit it must be positive. A zero/negative limit can never hold even one message, so the constructor fails fast with ValueError instead of producing an eternally empty context.

Source

Thrown at python/packages/autogen-core/src/autogen_core/model_context/_token_limited_chat_completion_context.py:52

        tools (List[ToolSchema] | None): A list of tool schema to use in the context.
        initial_messages (List[LLMMessage] | None): A list of initial messages to include in the context.

    """

    component_config_schema = TokenLimitedChatCompletionContextConfig
    component_provider_override = "autogen_core.model_context.TokenLimitedChatCompletionContext"

    def __init__(
        self,
        model_client: ChatCompletionClient,
        *,
        token_limit: int | None = None,
        tool_schema: List[ToolSchema] | None = None,
        initial_messages: List[LLMMessage] | None = None,
    ) -> None:
        super().__init__(initial_messages)
        if token_limit is not None and token_limit <= 0:
            raise ValueError("token_limit must be greater than 0.")
        self._token_limit = token_limit
        self._model_client = model_client
        self._tool_schema = tool_schema or []

    async def get_messages(self) -> List[LLMMessage]:
        """Get at most `token_limit` tokens in recent messages. If the token limit is not
        provided, then return as many messages as the remaining token allowed by the model client."""
        messages = list(self._messages)
        if self._token_limit is None:
            remaining_tokens = self._model_client.remaining_tokens(messages, tools=self._tool_schema)
            while remaining_tokens < 0 and len(messages) > 0:
                middle_index = len(messages) // 2
                messages.pop(middle_index)
                remaining_tokens = self._model_client.remaining_tokens(messages, tools=self._tool_schema)
        else:
            token_count = self._model_client.count_tokens(messages, tools=self._tool_schema)
            while token_count > self._token_limit and len(messages) > 0:
                middle_index = len(messages) // 2

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Omit token_limit or pass None when you want the model client's own remaining-token logic.
  2. Otherwise pass a positive budget with headroom for at least one message plus the system prompt.
  3. Clamp computed budgets: `limit = token_limit if token_limit and token_limit > 0 else None`.

Example fix

# before
ctx = TokenLimitedChatCompletionContext(client, token_limit=max_tokens - used)  # <=0 -> ValueError

# after
remaining = max_tokens - used
ctx = TokenLimitedChatCompletionContext(
    client, token_limit=remaining if remaining > 0 else None
)
Defensive patterns

Strategy: validation

Validate before calling

effective_limit = token_limit if (token_limit is not None and token_limit > 0) else None
ctx = TokenLimitedChatCompletionContext(client, token_limit=effective_limit)

Prevention

When it happens

Trigger: `TokenLimitedChatCompletionContext(client, token_limit=0)` or negative; computing token_limit as `max_tokens - used_tokens` which goes to 0 or below once the conversation grows; passing a config default of 0 intending 'unlimited' — for that, pass token_limit=None or omit it.

Common situations: Dynamic budget calculations from model context windows; configs where 0 means 'not set'; mixing up the semantics with buffer_size-based contexts.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/583d2a753b2e96c0. Report an issue: GitHub.