Repository navigation
Python: [Bug]: HandoffBuilder drops Agent additional properties during execution #7750
Copy link
Copy link
Closed
Copy link
Labels
orchestrationUsage: [Issues, PRs], Target: multi-agent orchestration (high-level patterns)Usage: [Issues, PRs], Target: multi-agent orchestration (high-level patterns)pythonUsage: [Issues, PRs], Target: PythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
Description
Activity
- addedpythonUsage: [Issues, PRs], Target: PythonUsage: [Issues, PRs], Target: PythontriageUsage: [Issues], Target: All issues that still need to be triagedUsage: [Issues], Target: All issues that still need to be triaged
on Aug 19, 2026 github-actions commented
on Aug 19, 2026 on Aug 19, 2026 – with GitHub ActionsContributorMore actions🤖 Automated triage reproduction notes (agent-authored — trust but verify)
Agent analysis
Repro: HandoffAgentExecutor._clone_chat_agent() in python/packages/orchestrations/agent_framework_orchestrations/_handoff.py (line 294) constructs a new Agent without passing additional_properties=agent.additional_properties, so the clone defaults to {}. Minimal repro: create an Agent with additional_properties, add middleware that reads context.agent.additional_properties, run via HandoffBuilder — middleware sees empty dict.
- Failing test:
python/packages/orchestrations/tests/test_handoff_additional_properties_bug.py - Files examined: python/packages/orchestrations/agent_framework_orchestrations/_handoff.py, python/packages/core/agent_framework/_agents.py, python/packages/orchestrations/tests/test_handoff.py
- Tests run: python/packages/orchestrations/tests/test_handoff_additional_properties_bug.py
- Reported version:
1.0.2 - Current version:
1.1.0
- Failing test:
- addedreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowUsage: [Issues], Target: all issues that can be reproduced by the triage workfloworchestrationUsage: [Issues, PRs], Target: multi-agent orchestration (high-level patterns)Usage: [Issues, PRs], Target: multi-agent orchestration (high-level patterns)and removedtriageUsage: [Issues], Target: All issues that still need to be triagedUsage: [Issues], Target: All issues that still need to be triaged
on Aug 19, 2026 - added a commit that references this issue
on Aug 19, 2026 - added a commit that references this issue
on Aug 19, 2026
Metadata
Metadata
Assignees
Labels
orchestrationUsage: [Issues, PRs], Target: multi-agent orchestration (high-level patterns)Usage: [Issues, PRs], Target: multi-agent orchestration (high-level patterns)pythonUsage: [Issues, PRs], Target: PythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
Type
Projects
- StatusShow more project fieldsDone
Description
Agents configured with
additional_propertieslose those properties when executed through a handoff workflow.The same agent exposes its configured properties during a direct run, but middleware sees an empty dictionary when the agent runs through
HandoffBuilder.This breaks middleware and integrations that use agent metadata for tenant information, tracing tags, feature flags, or other application-specific configuration.
Expected behavior
Agents participating in a handoff workflow should retain their configured
additional_properties.Actual behavior
The original agent retains its properties, but the agent executed by the handoff workflow has no additional properties.
Code Sample
import asyncio from collections.abc import Awaitable, Mapping, Sequence from typing import Any from agent_framework import ( Agent, AgentContext, BaseChatClient, ChatOptions, ChatResponse, Message, ) from agent_framework.orchestrations import HandoffBuilder seen: list[dict[str, Any]] = [] class FakeClient(BaseChatClient[ChatOptions[Any]]): model = "fake" def _inner_get_response( self, *, messages: Sequence[Message], stream: bool, options: Mapping[str, Any], **kwargs: Any, ) -> Awaitable[ChatResponse]: async def respond() -> ChatResponse: return ChatResponse( messages=[Message("assistant", ["done"])] ) return respond() async def observe(context: AgentContext, call_next) -> None: seen.append(dict(context.agent.additional_properties)) await call_next() async def main() -> None: coordinator = Agent( client=FakeClient(), name="coordinator", additional_properties={ "tenant": "contoso", "trace_tag": "triage", }, middleware=[observe], require_per_service_call_history_persistence=True, ) specialist = Agent( client=FakeClient(), name="specialist", require_per_service_call_history_persistence=True, ) await coordinator.run("hello") print("Direct run:", seen) seen.clear() workflow = ( HandoffBuilder( participants=[coordinator, specialist], termination_condition=lambda conversation: any( message.role == "assistant" for message in conversation ), ) .with_start_agent(coordinator) .build() ) await workflow.run("hello") print("Configured:", coordinator.additional_properties) print("Handoff run:", seen) asyncio.run(main()) Actual output: Direct run: [{'tenant': 'contoso', 'trace_tag': 'triage'}] Configured: {'tenant': 'contoso', 'trace_tag': 'triage'} Handoff run: [{}] Expected handoff output: Handoff run: [{'tenant': 'contoso', 'trace_tag': 'triage'}]Error Messages / Stack Traces
Package Versions
agent-framework-orchestrations: 1.0.2
Python Version
Python 3.12.10
Additional Context
Issue #5173 previously reported that handoff execution discarded function middleware. PR #5220 fixed middleware preservation, but
additional_propertiesremain unpreserved. This report concerns a separate public agent configuration field.