microsoft / microsoft/agent-framework

.NET: [Bug]: Declarative workflows silently skip unsupported actions

Open
#8,040 1 comment 0 reactions 1 assignee Claimed by @peibekwe View on GitHub
.NET declarative reproduced workflows
Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
2d 45m
Merged PRs (30d)
358

Description

### Description

`WorkflowActionVisitor` routes 32 declarative action kinds to `NotSupported`. When a workflow contains one, the action is skipped, the run continues, and it completes successfully. Nothing reaches the caller to say that part of the workflow did not execute.

A workflow whose YAML calls `SearchKnowledgeSources` or `InvokeFlowAction` therefore reports success while never performing the retrieval or invoking the flow.

#### What happens

`NotSupported` is the whole of the handling:

```csharp
private void NotSupported(DialogAction item)
{
Debug.WriteLine($"> UNKNOWN: ...{FormatItem(item)} => {FormatParent(item)}");
this.HasUnsupportedActions = true;
}
```

Neither of those two signals is available to an application:

1. `Debug.WriteLine` is `System.Diagnostics.Debug`, which is `[Conditional("DEBUG")]`. The call is removed by the compiler in Release, so a shipped app gets no output at all.
2. `HasUnsupportedActions` is declared on `WorkflowActionVisitor`, which is `internal sealed`. It is not reachable from outside the assembly. Across the repository it is read in exactly one place, and that place is a unit test (`DeclarativeWorkflowTest`).

So in a Release build the skip leaves no trace anywhere.

#### Why this is awkward today

The visitor already has an `ILoggerFactory` on the same code path, and already uses it when it attaches a logger to each executor:

```csharp
executor.Logger = this._workflowOptions.LoggerFactory.CreateLogger(executor.Id);
```

A warning through that factory, naming the action kind and id, would make the skip visible without changing any control flow.

#### The actions currently affected

`ActivateExternalTrigger`, `AdaptiveCardPrompt`, `AnswerQuestionWithAI`, `BeginDialog`, `CSATQuestion`, `CreateSearchQuery`, `DeleteActivity`, `DisableTrigger`, `DisconnectedNodeContainer`, `EmitEvent`, `GetActivityMembers`, `GetConversationMembers`, `InvokeAIBuilderModelAction`, `InvokeConnectorAction`, `InvokeCustomModelAction`, `InvokeFlowAction`, `InvokeSkillAction`, `LogCustomTelemetryEvent`, `OAuthInput`, `RecognizeIntent`, `RepeatDialog`, `ReplaceDialog`, `SearchAndSummarizeContent`, `SearchAndSummarizeWithCustomModel`, `SearchKnowledgeSources`, `SignOutUser`, `TransferConversation`, `TransferConversationV2`, `UnknownDialogAction`, `UpdateActivity`, `WaitForConnectorTrigger`.

I appreciate this list is expected to shrink as more actions gain support, which is what `HasUnsupportedActions` looks like it was put there to track. The gap is that nothing surfaces it while an action is still on the list.

### Error Messages / Stack Traces

None, and that is the substance of the report. The workflow completes without an error, a warning, or a log line.

### Package Versions

Microsoft.Agents.AI.Workflows.Declarative

### .NET Version

.NET 10.0

### Additional Context

Verified on `main` at commit 4507512f.

If you agree the silent skip is unintended, I would like to take this on. My thinking is a warning logged through the existing `LoggerFactory` from inside `NotSupported`, plus a unit test, since that changes no control flow and adds no public API surface. Happy to go a different way if you would rather surface it through the workflow model or an event, or to close this if the current behavior is deliberate.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.