Skip to content

[BUG] GraphNode.reset_executor_state() corrupts MultiAgentBase executor state #1775

@pgrayy

Description

@pgrayy

Checks

  • I have updated to the lastest minor and patch version of Strands
  • I have checked the documentation and this is not expected behavior
  • I have searched ./issues and there are no duplicates of my issue

Strands Version

main (latest)

Python Version

3.10+

Operating System

All

Installation Method

pip

Steps to Reproduce

  1. Create a Graph with a nested MultiAgentBase executor (e.g., a nested Graph)
  2. Either:
    • Enable reset_on_revisit and create a cycle that revisits the nested graph node, OR
    • Use session persistence and deserialize a completed graph run (no next_nodes_to_execute)
  3. The nested executor's GraphState gets overwritten with an AgentState

Expected Behavior

reset_executor_state() should handle MultiAgentBase executors correctly — either by resetting their state to the appropriate type or by skipping the reset for executor types that don't use AgentState.

Actual Behavior

reset_executor_state() checks hasattr(self.executor, "state") without distinguishing executor type. Since Graph (a MultiAgentBase) has a .state attribute (GraphState), the method overwrites it with an AgentState instance:

def reset_executor_state(self) -> None:
    if hasattr(self.executor, "messages"):
        self.executor.messages = copy.deepcopy(self._initial_messages)

    if hasattr(self.executor, "state"):
        self.executor.state = AgentState(self._initial_state.get())  # Wrong type for MultiAgentBase

    self.execution_status = Status.PENDING
    self.result = None

Note: __post_init__ has a guard (hasattr(self.executor.state, "get")) that prevents capturing the initial state for MultiAgentBase, so _initial_state stays as an empty AgentState(). But reset_executor_state lacks this guard.

Two call sites are affected:

  • _execute_node: guarded by reset_on_revisit (off by default), so only triggers if user opts in with a nested graph in a cycle
  • deserialize_state: unguarded — iterates all nodes unconditionally when restoring a completed run

Possible Solution

Add type-aware handling in reset_executor_state(). For example, only reset AgentState-based executors, and for MultiAgentBase executors either call their own reset mechanism or skip the state reset.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions