Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Improves resilience of declarative workflow executors when an invoked agent returns an AgentResponse/ExternalInputResponse with zero Messages, avoiding deterministic crashes caused by unguarded .Last() / .Single() calls.
Changes:
- Replace
.Last()usages withLastOrDefault()+ null-guards across multiple executors to avoid “Sequence contains no elements”. - Skip JSON response-object assignment when there is no final message text to parse.
- Add unit tests covering empty-message responses for
RequestExternalInputExecutor.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/RequestExternalInputExecutor.cs | Avoids .Last() crash when external input contains no messages. |
| dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/QuestionExecutor.cs | Adds defensive handling around selecting the “input” message from an extracted response. |
| dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeAzureAgentExecutor.cs | Avoids .Last() crash on resume and guards JSON parsing when last message is missing/empty. |
| dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Foundry/AzureAgentProvider.cs | Replaces .Single() with explicit cardinality check + clearer exception messages. |
| dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/ObjectModel/RequestExternalInputExecutorTest.cs | Adds coverage for empty-message responses (with and without workflow conversation). |
westey-m
approved these changes
Apr 21, 2026
lokitoth
approved these changes
Apr 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
Declarative workflow runs that include InvokeAzureAgent actions could crash with:
The crash is deterministic whenever an invoked agent returns an AgentResponse with zero Messages (e.g., a tool-only
turn where the model emits remote_function_call / mcp_call items without a final assistant text message,
content-filtered responses, or streams that close before the terminal assistant message). When that happens, the
executor's unguarded
.Laston the empty collection throws,DeclarativeActionExecutorwraps it as Unhandledworkflow failure - #{id} ({ModelType}), and the entire run terminates mid-pipeline — subsequent actions never
execute, so downstream side effects never happen.
Fixes #5375
Description
Replace unguarded
.Last/.Singleon response-message collections with defensive access that degrades gracefully.Contribution Checklist