Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Python: [Bug]: HandoffBuilder store=False breaks FunctionInvocationLayer tool result submission #4376

Description

@omargalal20

Description

What happened

When using HandoffBuilder with AzureOpenAIResponsesClient, the workflow crashes with openai.BadRequestError: Item with id 'rs_...' not found after a tool call completes and the framework tries to submit the tool result back to the model.
HandoffBuilder._clone_chat_agent() forces store=False (line 373 of _handoff.py). This is intentional — handoff workflows manage conversation state explicitly. However, the FunctionInvocationLayer's streaming tool loop (_tools.py, line 2280-2282) still captures response.conversation_id from the streaming response and passes it as previous_response_id on the next iteration (the tool result submission). Since store=False means the response was never persisted server-side, the API rejects the reference.

What I expected to happen

The tool invocation loop should respect store=False by not setting conversation_id/previous_response_id when store is disabled. When store=False, the loop should replay the full message history (including the tool call + tool result) instead of referencing a non-persisted response ID.

Steps to reproduce

  1. Create agents with AzureOpenAIResponsesClient and register tools on them
  2. Build a HandoffBuilder workflow with those agents
  3. Run the workflow with stream=True
  4. Send a message that triggers a tool call (e.g., verify_patient)
  5. After the tool executes, the framework crashes when submitting the tool result

Code Sample

from agent_framework import Agent, tool
from agent_framework.azure import AzureOpenAIResponsesClient
from agent_framework.orchestrations import HandoffBuilder
from azure.identity import AzureCliCredential

@tool(approval_mode="never_require")
def verify_patient(full_name: str, date_of_birth: str) -> dict:
    return {"verified": True, "patient_id": "P-12345"}

client = AzureOpenAIResponsesClient(
    project_endpoint="...",
    deployment_name="gpt-5.1-chat",
    credential=AzureCliCredential(),
)

agent_a = client.as_agent(name="agent_a", instructions="...", tools=[verify_patient])
agent_b = client.as_agent(name="agent_b", instructions="...")

builder = HandoffBuilder(name="demo", participants=[agent_a, agent_b])
builder.add_handoff(agent_a, [agent_b])
workflow = builder.with_start_agent(agent_a).build()

# Trigger a message that causes agent_a to call verify_patient
# → After tool executes, framework crashes on tool result submission
stream = workflow.run("Verify patient Omar, DOB 2000-09-14", stream=True)
async for event in stream:
    pass  # Crashes here

Error Messages / Stack Traces

openai.BadRequestError: Error code: 400 - {'error': {'message': "Item with id 'rs_...' not found. Items are not persisted when `store` is set to false.", ...}}


**Root cause in framework code:**
- `_handoff.py` line 373: forces `"store": False`
- `_tools.py` line 2280-2282 (streaming path): captures `response.conversation_id` and sets it via `_update_conversation_id`, which causes the next API call to include `previous_response_id` referencing a non-persisted response

Package Versions

agent-framework: 1.0.0rc2, agent-framework-azure-ai: 1.0.0rc2, agent-framework-orchestrations: 1.0.0b260225

Python Version

Python 3.12

Additional Context

This also affects the non-streaming path (_tools.py line 2146-2147). The _get_conversation_id method correctly returns None when store=False, but the FunctionInvocationLayer reads response.conversation_id directly from the ChatResponse object, bypassing the store check.

Metadata

Metadata

Assignees

Labels

bugUsage: [Issues], Target: all issues (Legacy, prefer issue type: bug)pythonUsage: [Issues, PRs], Target: Python

Type

Fields

No fields configured for Bug.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions