Skip to content

BUG: Duplicate action_step yield and NameError when max_steps=0 #1816

@AhnJoonSung

Description

@AhnJoonSung

Problem
I found two issues in the _run_stream method of the MultiStepAgent class (src/smolagents/agents.py, lines 537-606):

  1. Duplicate yield when max_steps is reached: When an agent reaches max_steps, the final action_step gets yielded twice - once in the finally block (line 601) and again on line 605. This causes consumers of the stream to receive duplicate step events.

  2. NameError when max_steps=0: If max_steps is set to 0, the while loop never executes, so action_step is never defined. However, line 605 tries to yield this undefined variable, causing a NameError.

Steps to reproduce

For the duplicate yield issue:

  1. Create an agent with max_steps=2
  2. Run the agent with stream=True
  3. The agent will execute 2 steps
  4. On the final step (step 2), the while loop executes normally
  5. The finally block on line 601 yields the action_step for step 2
  6. step_number is incremented to 3, causing the while loop to exit
  7. The condition on line 604 evaluates to True (returned_final_answer is False and step_number is 3)
  8. Line 605 tries to yield action_step again, causing a duplicate

For the NameError issue:

  1. Create an agent with max_steps=0
  2. Run the agent with stream=True
  3. The while loop condition (step_number <= 0) is False from the start, so the loop never executes
  4. action_step is never defined because it's only created inside the while loop
  5. The condition on line 604 evaluates to True (returned_final_answer is False and step_number is 1)
  6. Line 605 tries to yield action_step, but it was never defined, causing a NameError

Actual behavior and error logs

This analysis is based on code review rather than runtime errors. Based on the code logic:

For the duplicate yield case (max_steps > 0):

  • When the agent reaches max_steps, the execution flow leads to the same action_step being yielded twice
  • First yield happens in the finally block (line 601) as part of normal step execution
  • Second yield happens on line 605 when the condition on line 604 is True
  • This means stream consumers would receive duplicate action_step events for the final step

For the NameError case (max_steps = 0):

  • The while loop never executes because step_number (1) is not <= max_steps (0)
  • Since action_step is only created inside the while loop (line 569), it never gets defined
  • When line 604's condition evaluates to True, line 605 attempts to yield action_step
  • Since action_step was never defined, this would raise a NameError: local variable 'action_step' referenced before assignment

The root cause is that line 605 assumes action_step is always defined, but this is only true when the while loop has executed at least once.

Expected behavior

  1. Each action_step should only be yielded once
  2. The code should handle edge cases like max_steps=0 gracefully without errors
  3. Line 605 should be removed since action_step is already yielded in the finally block

Environment:

  • OS: Windows 11
  • Python version: 3.13.3
  • Package version: latest (main branch)

Checklist

  • I have searched the existing issues and have not found a similar bug report.
  • I have provided a minimal, reproducible example.
  • I have provided the full traceback of the error.
  • I have provided my environment details.
  • I am willing to work on this issue and submit a pull request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions