Description
Summary
With two approval-gated calls to the same tool in one assistant message, approving the first, reloading the page while the second card is pending, and then approving the restored card can kill the run:
ValueError: Approval alias conflicts with an existing pending occurrence.
The user sees the generic run-failure line and the approval card is re-offered; the turn is lost.
Stack (entirely upstream — no application frame raises)
agent_framework_ag_ui/_agent_run.py:_run_agent_stream
→ _agent_run.py:1002 _pop_collected_tool_approval_response_messages
→ _agent_run.py:928 _register_server_generated_approval_response
→ _approval_lifecycle.py:295 ApprovalLifecycle.register
→ _approval_lifecycle.py:366 _register_aliases
raise ValueError("Approval alias conflicts with an existing pending occurrence.")
The application's frames are above _run_agent_stream only (our AG-UI wrapper and run buffer); everything from the collection of approval-response messages down is framework code.
Reproduction
Environment: agent-framework-core 1.19.0 / agent-framework-ag-ui 1.4.0 at 72325696, AG-UI host + the reference CopilotKit client, provider ollama, model glm-5.3-flash:cloud.
- Register one approval-gated tool. Ours is an MCP tool (
microsoft_docs_search) with approval required.
- Prompt so the model emits two parallel calls to that same tool in one message ("look up BOTH X AND Y in the same step").
- Two tool chips appear "Running"; one approval card is offered.
- Approve it. The first call completes; the second card appears.
- Reload the page while the second card is pending. The transcript and the pending card are restored correctly — this part works.
- Approve the restored card.
Expected: the second call executes and the run completes, as it does without step 5.
Actual (1 of 3 attempts): the run ends with RUN_ERROR, the server logs the ValueError above, and the card is re-offered.
Code Sample
Error Messages / Stack Traces
Package Versions
agent-framework-core: 1.19.0, agent-framework-ag-ui: 1.4.0
Python Version
No response
Additional Context
What the same flow does without the reload
Identical prompt and approvals with no reload between them completed correctly on every attempt, both calls executing and the model producing its answer. So the batched-approval path itself is healthy — this is specific to re-registering a server-generated approval response on the resume path.
Note on what changed
_register_server_generated_approval_response and the ApprovalLifecycle alias registry are part of the 1.19.0 approval rework (PRs #8433, #8449, #8428). The same application code on agent-framework-core 1.18.0 did not produce this error in equivalent use. That is circumstantial rather than bisected, and the report should present it that way.
Suggested direction
On the resume path an alias that is already registered for a pending occurrence of the same call is more likely a replay of that occurrence than a genuine conflict. Treating a re-registration of an identical (call_id, alias) pair as idempotent — returning the existing occurrence instead of raising — would make the reconnect case safe without weakening the conflict check for genuinely distinct occurrences.
Description
Summary
With two approval-gated calls to the same tool in one assistant message, approving the first, reloading the page while the second card is pending, and then approving the restored card can kill the run:
The user sees the generic run-failure line and the approval card is re-offered; the turn is lost.
Stack (entirely upstream — no application frame raises)
The application's frames are above
_run_agent_streamonly (our AG-UI wrapper and run buffer); everything from the collection of approval-response messages down is framework code.Reproduction
Environment:
agent-framework-core1.19.0 /agent-framework-ag-ui1.4.0 at72325696, AG-UI host + the reference CopilotKit client, providerollama, modelglm-5.3-flash:cloud.microsoft_docs_search) with approval required.Expected: the second call executes and the run completes, as it does without step 5.
Actual (1 of 3 attempts): the run ends with
RUN_ERROR, the server logs theValueErrorabove, and the card is re-offered.Code Sample
Error Messages / Stack Traces
Package Versions
agent-framework-core: 1.19.0, agent-framework-ag-ui: 1.4.0
Python Version
No response
Additional Context
What the same flow does without the reload
Identical prompt and approvals with no reload between them completed correctly on every attempt, both calls executing and the model producing its answer. So the batched-approval path itself is healthy — this is specific to re-registering a server-generated approval response on the resume path.
Note on what changed
_register_server_generated_approval_responseand theApprovalLifecyclealias registry are part of the 1.19.0 approval rework (PRs #8433, #8449, #8428). The same application code onagent-framework-core1.18.0 did not produce this error in equivalent use. That is circumstantial rather than bisected, and the report should present it that way.Suggested direction
On the resume path an alias that is already registered for a pending occurrence of the same call is more likely a replay of that occurrence than a genuine conflict. Treating a re-registration of an identical (call_id, alias) pair as idempotent — returning the existing occurrence instead of raising — would make the reconnect case safe without weakening the conflict check for genuinely distinct occurrences.