microsoft / microsoft/agent-framework
Python: [DevUI] HITL approval fails with "'str' object has no attribute 'name'" - FunctionApprovalRequestContent serialization issue
@victordibia is already working on this.
Since Jan 6, 2026.
- Dominant language
- Python
- Stars
- 13.6k
- Forks
- 2.3k
- Avg merge
- 2d 45m
- Merged PRs (30d)
- 358
Description
## Description
When using `approval_mode="always_require"` on an `@ai_function` and attempting to approve the HITL request through DevUI, the approval submission fails with the error:
```
'str' object has no attribute 'name'
```
## Environment
- **agent-framework version**: 1.0.0b251028
- **agent-framework-devui version**: 1.0.0b251028
- **Python version**: 3.11
- **OS**: Windows 11
## Steps to Reproduce
1. Define an `@ai_function` with `approval_mode="always_require"`:
```python
@ai_function(
name="request_escalation_approval",
description="Request human approval for escalation.",
approval_mode="always_require",
)
def request_escalation_approval(
param1: str,
param2: float,
escalation_reason: str,
) -> FunctionResultContent:
return FunctionResultContent(call_id=str(uuid.uuid4()), result={"status": "approved"})
```
2. Create a workflow using `WorkflowBuilder`:
```python
from agent_framework import WorkflowBuilder
from agent_framework.devui import serve
workflow = (
WorkflowBuilder()
.add_agent(my_agent)
.set_start_executor(my_agent)
.build()
)
serve([workflow], auto_open=True, port=8077)
```
3. Send a message that triggers the function with `approval_mode="always_require"`
4. DevUI shows the approval request card with Approve/Reject buttons
5. Click **Approve**
6. Error occurs: `'str' object has no attribute 'name'`
## Expected Behavior
Clicking "Approve" in DevUI should:
1. Serialize the approval response correctly
2. Call `workflow.send_responses_streaming({request_id: request.data.create_response(approved=True)})`
3. Resume the workflow with the approved function call
## Actual Behavior
The approval submission fails because `function_call` is serialized as a string instead of an object. When the framework tries to access `function_call.name`, it fails because strings don't have a `.name` attribute.
## Root Cause Analysis
Based on code review, the issue appears to be in how DevUI serializes/deserializes `FunctionApprovalRequestContent` when sending the approval response back to the workflow. The `function_call` field is being serialized to a string representation instead of maintaining its object structure.
Looking at the official samples (e.g., `sequential_builder_tool_approval.py`), the correct pattern is:
```python
async for event in workflow.run_streaming(...):
if isinstance(event, RequestInfoEvent):
for request in event.data.user_input_requests:
if isinstance(request.data, FunctionApprovalRequestContent):
responses[request.request_id] = request.data.create_response(approved=True)
await workflow.send_responses_streaming(responses)
```
However, DevUI's frontend-to-backend serialization appears to break this flow.
## Workaround
Change `approval_mode` from `"always_require"` to `"auto"` to bypass the HITL flow entirely:
```python
@ai_function(
name="request_escalation_approval",
description="...",
approval_mode="auto", # Workaround: bypass DevUI serialization bug
)
def request_escalation_approval(...):
print("🔔 Auto-approved (HITL disabled)")
return FunctionResultContent(...)
```
## Additional Context
- The issue occurs specifically when using DevUI; programmatic HITL handling (as shown in the samples) works correctly
- Both `WorkflowBuilder` and `HandoffBuilder` exhibit the same issue when used with DevUI
- The approval card renders correctly in DevUI; only the submission fails
## Related Files
- `samples/workflow_samples/sequential_builder_tool_approval.py` - shows correct HITL pattern
- `samples/workflow_samples/group_chat_builder_tool_approval.py` - shows correct HITL pattern
- DevUI frontend: `src/agent-framework-devui/src/app/components/...`
---
Would appreciate a fix or guidance on the correct way to handle HITL approvals through DevUI. Thank you!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.