Skip to content

[Bug] planner_max_steps=0 still triggers "paused after 12 tool-call rounds" limit #4166

@tang-zhilei

Description

@tang-zhilei

Bug Description

Setting agent.planner_max_steps = 0 in config (which should mean "unlimited") still causes the planner to pause after 12 tool-call rounds with the error:

planner: paused after 12 tool-call rounds (agent.planner_max_steps) — the work so far is saved; send another message to continue, or set agent.planner_max_steps higher or to 0 for no limit

Environment

  • Reasonix version: (please fill in, e.g., 0.47.x or git commit hash)
  • Mode: CLI / Desktop / TUI (please specify)
  • Config method: reasonix.toml / environment variable / CLI flag

Configuration

[agent]
planner_max_steps = 0   # should be unlimited
executor_max_steps = 0  # should be unlimited

Expected Behavior

With planner_max_steps = 0, the planner should be able to run unlimited tool-call rounds without hitting a step limit.

Actual Behavior

The planner pauses at exactly 12 rounds (the default value for planner_max_steps), as if the config setting of 0 is not being recognized.

Code Analysis

I traced the relevant code paths and found:

  1. Default value: internal/config/config.go:994 — default is 12
  2. TOML decoding: internal/config/config.go:665PlannerMaxSteps int \toml:"planner_max_steps"``
  3. Config to coordinator: internal/boot/boot.go:860-862 — passes cfg.Agent.PlannerMaxSteps to agent.Options{MaxSteps: ...}
  4. Loop condition: internal/agent/agent.go:539for step := 0; a.maxSteps <= 0 || step < a.maxSteps; step++
  5. Error generation: internal/agent/agent.go:667 — returns the pause error when loop exits
  6. Existing test: coordinator_test.go has TestCoordinatorPlannerMaxStepsZeroIsUnlimited confirming that MaxSteps=0 should be unlimited in unit tests

The code logic at line 539 (a.maxSteps <= 0 || step < a.maxSteps) correctly treats 0 as unlimited. However, the fact that the error fires at exactly 12 (the default) suggests the config value 0 is not being applied correctly — perhaps the TOML decode step is not overwriting the default when the value is 0.

Possible Root Cause

When using toml.DecodeFile(path, cfg) into a struct already initialized with defaults (via Default()), if the TOML library treats 0 as an omitted/unset value, it may not overwrite the existing default field value. Alternatively, there might be a merge/override issue in the configuration loading chain.

Steps to Reproduce

  1. Set planner_max_steps = 0 in reasonix.toml
  2. Start a coding session where the planner needs more than 12 read-only tool calls
  3. Observe the planner pausing after 12 rounds with the error message above

Suggested Fix

  • Verify that toml.DecodeFile correctly overwrites PlannerMaxSteps from 12 (default) to 0 when the config file explicitly sets planner_max_steps = 0
  • Consider adding an end-to-end test that loads a config with planner_max_steps = 0 and verifies the planner loop runs beyond 12 rounds

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentCore agent loop (internal/agent, internal/control)configConfiguration & setup (internal/config)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions