#23297·llama_index

[Bug]: max_iterations=0 is silently replaced by the default 20

Author: chrikrahCreated Sep 28, 2026Updated Sep 28, 2026

Bug Description

max_iterations=0 is silently replaced by the default of 20, so a run that asks for no iterations executes tools and answers normally. BaseWorkflowAgent._init_context reads the value with or:

python
# llama-index-core/llama_index/core/agent/workflow/base_agent.py:305-309
if not await ctx.store.get("max_iterations", default=None):
    max_iterations = (
        ev.get("max_iterations", default=None) or DEFAULT_MAX_ITERATIONS
    )

0 is falsy, so it never reaches the store. AgentWorkflow._init_context has the same line. Every other guard downstream is then comparing against 20, and the caller is given no signal.

Related but different: #23051 is the outer if not await ctx.store.get(...), which ignores the keyword when a Context is reused. This is the inner or, and it fires on a fresh Context.

Version

llama-index-core 0.14.25, measured at main 169e450.

Steps to Reproduce

python
# no network and no model: the mock counts the calls it is asked for
agent = FunctionAgent(name="agent", description="test", tools=[counting_tool], llm=mock_llm)
await agent.run(user_msg="test", max_iterations=0)

The mock answers a tool call first and a final answer second.

Relevant Logs/Tracebacks

$ PYTHONPATH=llama-index-core llama-index-core/.venv/bin/python probe_boundary_cases.py   # 169e450
C max_iterations=0, tool round then answer   llm_calls=2 tool_runs=1  ok response='answer is 42'

Two model calls and one tool run, under a limit of zero. The same agent at max_iterations=1 stops after one call, which is the guard working.

Either reading is defensible and the choice is yours: 0 means the run stops before the first model call, or 0 is invalid and .run() raises. Both are a one-line change from or to an is None check plus a validation. Would you like it as a pull request, and which of the two?

I used an AI assistant to write the probe. Every number above came from a local run, and I checked each one before filing.