deepset-ai/haystack · error
`max_total_tokens` must be a positive number of tokens, got
Error message
`max_total_tokens` must be a positive number of tokens, got {max_total_tokens}. What it means
WallClockTokenBudget (haystack/hooks/budget/hooks.py) requires max_total_tokens to be a positive integer of tokens. A value less than 1 (0, negative, or otherwise falsy-as-small) would make the Agent stop immediately or behave nonsensically, so __init__ raises this ValueError with the offending value.
Source
Thrown at haystack/hooks/budget/hooks.py:58
hooks={"before_llm": [TokenBudgetHook(max_total_tokens=100_000)]},
)
result = agent.run(messages=[...])
```
"""
allowed_hook_points = ("before_llm",)
def __init__(self, *, max_total_tokens: int, add_final_message: bool = False) -> None:
"""
Create a token budget hook.
:param max_total_tokens: Maximum cumulative token usage before the Agent is stopped.
:param add_final_message: Whether to append an assistant message explaining why the Agent stopped.
:raises ValueError: If `max_total_tokens` is less than 1.
"""
if max_total_tokens < 1:
raise ValueError(f"`max_total_tokens` must be a positive number of tokens, got {max_total_tokens}.")
self.max_total_tokens = max_total_tokens
self.add_final_message = add_final_message
def run(self, state: State) -> None:
"""
Stop the Agent if its cumulative token usage has reached the budget.
:param state: Agent state containing the cumulative token usage.
"""
usage = state.data.get("token_usage") or {}
# Not every chat generator reports `total_tokens`, so fall back to summing the input and output keys across
# the known naming conventions.
total_tokens = _first_numeric(usage, ("total_tokens",))
if not total_tokens:
total_tokens = _first_numeric(usage, _INPUT_TOKEN_KEYS) + _first_numeric(usage, _OUTPUT_TOKEN_KEYS)
if total_tokens >= self.max_total_tokens:
logger.warning(
"Agent reached its token budget of {max_total_tokens} ({total_tokens} used); requesting a stop.",View on GitHub (pinned to e318778c9b)
Solutions
- Pass a positive integer, e.g. WallClockTokenBudget(max_total_tokens=10000).
- Fix the config/env lookup so the value defaults to a sensible positive number.
- Validate/normalize before constructing: max(1, int(configured_value)).
Example fix
// before
budget = WallClockTokenBudget(max_total_tokens=int(os.getenv('MAX_TOKENS', 0)))
// after
max_tokens = int(os.getenv('MAX_TOKENS', '10000'))
budget = WallClockTokenBudget(max_total_tokens=max(1, max_tokens)) Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(max_total_tokens, int) or max_total_tokens < 1:
raise ValueError('max_total_tokens must be a positive integer') Type guard
def is_positive_int(v: object) -> bool:
return isinstance(v, int) and not isinstance(v, bool) and v >= 1 Try / catch
try:
budget = WallClockTokenBudget(max_total_tokens=cfg['max_total_tokens'])
except ValueError as e:
if 'max_total_tokens' in str(e):
budget = WallClockTokenBudget(max_total_tokens=10000)
else:
raise Prevention
- Never default the token budget to 0; use a sane positive default
- Validate env/config values with int() and a lower bound before constructing
- Use type annotations (max_total_tokens: int) and a type checker to catch bad inputs
When it happens
Trigger: Instantiating WallClockTokenBudget-like budget hook with max_total_tokens=0, a negative number, or a value computed from an empty/failed config lookup (e.g. int(os.getenv('MAX_TOKENS', 0))).
Common situations: Environment variable for the budget missing so the default 0 is used; copying an example that left the placeholder at 0; a unit conversion bug producing a negative value.
Related errors
- No tools were configured for the Agent at initialization.
- tools must be a list of Tool and/or Toolset objects, a Tools
- StateSchema: Key '{param}' is missing a 'type' entry.
- StateSchema: 'type' for key '{param}' must be a Python type,
- StateSchema: 'handler' for key '{param}' must be callable or
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/f876f3d460d73c8b.
Report an issue: GitHub.