Skip to content

.NET: [Bug]: Concurrency capability is not preserved by function and subworkflow bindings #8341

Description

Description

ExecutorBinding.SupportsConcurrentSharedExecution contributes to whether a workflow can be used with InProcessExecution.Concurrent.

I found two binding paths where the underlying concurrency capability is not preserved:

  1. BindAsExecutor(..., threadsafe: false) creates a FunctionExecutor that is not cross-run shareable, but the configured binding currently reports concurrent shared execution as supported.
  2. SubworkflowBinding reports concurrent shared execution as supported even when its child workflow is not concurrent-capable.

As a result, workflows can be accepted by the concurrent execution path even though one of the shared execution paths does not support concurrent runs.

The subworkflow case is independently reproducible using a direct non-shareable executor, so it does not depend on the function-binding behavior.

Expected behavior:

  • threadsafe: false, including the default value, should make a shared function binding ineligible for concurrent workflow runs.
  • threadsafe: true should remain eligible.
  • A subworkflow binding should reflect whether its child workflow supports concurrent runs.
  • Invalid concurrent execution should be rejected at the appropriate workflow boundary.

Code Sample

Function binding

Func<int, int> handler = static value => value;

ExecutorBinding binding =
    handler.BindAsExecutor("Function", threadsafe: false);

Workflow workflow =
    new WorkflowBuilder(binding).Build();

await using StreamingRun run =
    await InProcessExecution.Concurrent.OpenStreamingAsync(workflow);

// Actual: the concurrent run is accepted.
// Expected: InvalidOperationException.

Independent subworkflow case

static ValueTask HandleAsync(
    int message,
    IWorkflowContext context,
    CancellationToken cancellationToken) => default;

FunctionExecutor<int> childExecutor =
    new("Child", HandleAsync, declareCrossRunShareable: false);

Workflow child =
    new WorkflowBuilder(childExecutor.BindExecutor()).Build();

ExecutorBinding childBinding =
    child.BindAsExecutor("ChildWorkflow");

Workflow parent =
    new WorkflowBuilder(childBinding).Build();

await using StreamingRun run =
    await InProcessExecution.Concurrent.OpenStreamingAsync(parent);

// Actual: the parent passes the concurrent eligibility check.
// Expected: the parent is rejected because its child workflow is not
// concurrent-capable.

Error Messages / Stack Traces

No exception is produced at the affected eligibility boundary.

The expected behavior is the existing InvalidOperationException used when concurrent execution is requested for a workflow containing a binding that does not support concurrent shared execution.

Package Versions

Microsoft.Agents.AI.Workflows: 1.21.0

The same affected implementation is present in the dotnet-1.21.0 source tag. Runtime reproduction below was performed against current microsoft/agent-framework main; the release tag was inspected at source level only.

.NET Version

.NET SDK 10.0.401

Additional Context

The threadsafe parameter already describes whether a function handler may be used simultaneously by multiple runs. The function case appears to lose that capability when the FunctionExecutor is converted into a configured binding.

The subworkflow case appears to be the same capability-propagation issue at the workflow boundary: the child workflow can be non-concurrent while the binding presented to its parent reports concurrent support.

I have a small patch and deterministic regression coverage for both cases. If maintainers would prefer the subworkflow case to be handled separately, I am happy to split it into a follow-up.

I'm happy to work on the fix if this direction looks appropriate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

.NETUsage: [Issues, PRs], Target: .NetreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowworkflowsUsage: [Issues, PRs], Target: Workflows

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions