Skip to content

.NET: [Bug]: DeclarativeWorkflowBuilder.Build crashes under NativeAOT — 'Microsoft.Agents.ObjectModel.RecurrenceFrequency[]' is missing native code or metadata #9430

Open

Description

@QQJason

Observed Behavior

Publishing a console app that references Microsoft.Agents.AI.Workflows.Declarative with true compiles cleanly, but DeclarativeWorkflowBuilder.Build(...) throws at runtime, before any YAML is processed: TypeInitializationException whose innermost exception is NotSupportedException: 'Microsoft.Agents.ObjectModel.RecurrenceFrequency[]' is missing native code or metadata. The crash happens in a static constructor, so nothing declarative runs at all under NativeAOT. Impact: any NativeAOT-published or trim-aggressive app cannot use declarative workflows. The identical code works correctly on JIT (dotnet run).

Expected Behavior

DeclarativeWorkflowBuilder.Build should succeed under NativeAOT and the workflow should run, same as on JIT. If NativeAOT is not supported today, the build should fail with IL trim/AOT analysis warnings (or a documented explicit NotSupportedException at a defined API boundary) instead of crashing in a static constructor at runtime.

Steps to Reproduce

  1. Create a net10.0 console app with the csproj and sources from Minimal Reproduction below (PackageReference Microsoft.Agents.AI.Workflows.Declarative 1.25.0, PublishAot=true).
  2. Run: dotnet publish -c Release -r win-x64
  3. Run the published native exe: ./bin/Release/net10.0-windows/win-x64/publish/Repro.exe
  4. Observe: process exits non-zero with TypeInitializationException -> NotSupportedException 'Microsoft.Agents.ObjectModel.RecurrenceFrequency[]' is missing native code or metadata, thrown from DeclarativeWorkflowBuilder.Build.
  5. Control: run the same project with dotnet run (JIT) — it prints "built ok".

Minimal Reproduction

<!-- Repro.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAot>true</PublishAot>
    <NoWarn>$(NoWarn);MAAI001</NoWarn>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Agents.AI.Workflows.Declarative" Version="1.25.0" />
  </ItemGroup>
</Project>
// Program.cs
using Microsoft.Agents.AI.Workflows;
using Microsoft.Agents.AI.Workflows.Declarative;

const string yaml = """
kind: Workflow
trigger:
  kind: OnConversationStart
  id: wf
  actions:
    - kind: SetVariable
      id: set_input
      variable: Local.UserInput
      value: =System.LastMessage.Text
    - kind: SendActivity
      id: send
      activity: Hello
""";

// Any ResponseAgentProvider works; the YAML contains no agent actions, so it is never invoked.
var options = new DeclarativeWorkflowOptions(new MinimalAgentProvider());
var workflow = DeclarativeWorkflowBuilder.Build<string>(new StringReader(yaml), options); // throws here under AOT
Console.WriteLine("built ok");
// MinimalAgentProvider.cs — small in-memory stub; required only to satisfy the options constructor.
using System.Runtime.CompilerServices;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows.Declarative;
using Microsoft.Extensions.AI;

sealed class MinimalAgentProvider : ResponseAgentProvider
{
    private readonly Dictionary<string, List<ChatMessage>> _conversations = new();

    public override Task<string> CreateConversationAsync(CancellationToken ct = default)
    {
        string id = Guid.NewGuid().ToString();
        lock (_conversations) _conversations[id] = new();
        return Task.FromResult(id);
    }

    public override Task<ChatMessage> CreateMessageAsync(string conversationId, ChatMessage message, CancellationToken ct = default)
    {
        lock (_conversations) _conversations[conversationId].Add(message);
        return Task.FromResult(message);
    }

    public override Task<ChatMessage> GetMessageAsync(string conversationId, string messageId, CancellationToken ct = default)
        => Task.FromResult(new ChatMessage(ChatRole.Assistant, "stub"));

    public override async IAsyncEnumerable<ChatMessage> GetMessagesAsync(
        string conversationId, int? limit = null, string? after = null, string? before = null, bool ascending = true,
        [EnumeratorCancellation] CancellationToken ct = default)
    {
        List<ChatMessage> snapshot;
        lock (_conversations) snapshot = _conversations[conversationId].ToList();
        foreach (var m in snapshot) yield return m;
    }

    public override IAsyncEnumerable<AgentResponseUpdate> InvokeAgentAsync(
        string agentId, string? agentVersion, string? conversationId, IEnumerable<ChatMessage> messages,
        IDictionary<string, object?>? inputArguments, CancellationToken ct = default)
        throw new NotSupportedException();
}

Error Messages and Stack Traces

[env] IsAot=True (RuntimeFeature.IsDynamicCodeSupported=False)
[build] FAIL
System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerException's StackTrace property.
  at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x13a
System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerException's StackTrace property.
System.NotSupportedException: 'Microsoft.Agents.ObjectModel.RecurrenceFrequency[]' is missing native code or metadata. This can happen for code that is not compatible with trimming or AOT. Inspect and fix trimming and AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility

(exit code 2; dotnet run on JIT prints "built ok")

Publish-time warnings observed (IL3053/IL2104 on Microsoft.Agents.ObjectModel.Json and Microsoft.PowerFx.Core — trim warnings from dependency assemblies).

Package Versions

Microsoft.Agents.AI.Workflows.Declarative: 1.25.0 (and 1.24.0 — both reproduce identically) Microsoft.Agents.AI: 1.25.0 (and 1.24.0 — both reproduce identically) Microsoft.Agents.AI.Workflows: 1.25.0 (and 1.24.0) Transitive: Microsoft.Agents.ObjectModel.Json 2026.5.5, Microsoft.PowerFx.Core 1.8.1

.NET Version

.NET 10.0

Operating System

Windows

Regression

No

Additional Context

Workarounds already tried, none helped:

  1. TrimmerRootDescriptor + for Microsoft.Agents.ObjectModel — ILC still does not emit the array EEType.
  2. Anchoring the enum array types from app code — fixing RecurrenceFrequency[] just surfaces the next missing array (SkipQuestionMode[]).
  3. Registering a JsonSerializerContext — the failure is trim-metadata loss in a static constructor (no IL2026/IL3050 involved); the official DeclarativeJsonContext does not include these enums.
  4. DeclarativeWorkflowJsonOptions.Default — covers checkpoint serialization only; the Build-stage crash is unrelated and happens first.

Suspected cause: the PowerFx interpreter / Power Platform object model maps types reflectively; a static initializer materializes enum arrays whose EETypes ILC does not generate. Root cause is likely in Microsoft.Agents.ObjectModel / PowerFx interop; filing here because the Declarative package is the entry point users hit first.

Note the Learn page (https://learn.microsoft.com/en-us/agent-framework/workflows/declarative) documents an AOT checkpointing path (DeclarativeWorkflowJsonOptions.Default), which implies AOT support is intended — but Build itself is blocked before checkpointing is even relevant.

Acknowledgements

  • I searched existing issues and did not find a duplicate.
  • I personally verified this behavior and the reproduction details are authentic.
  • I will wait for explicit maintainer agreement before starting implementation of a non-trivial change.

Activity

  1. added theissue type on Oct 15, 2026
  2. added
    .NETUsage: [Issues, PRs], Target: .Net
    on Oct 15, 2026
  3. added
    reproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
    on Oct 15, 2026
  4. github-actions commented on Oct 15, 2026

    @github-actions
    Contributor

    🤖 Automated triage reproduction notes (agent-authored — trust but verify)

    Agent analysis

    The repro enters dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DeclarativeWorkflowBuilder.cs:ReadWorkflow and fails during ObjectModel YAML value-expression parsing when SystemOptionSetDataTypeGreen initializes RecurrenceFrequency[]. Publish the included repro for net10.0 with NativeAOT and run it; the JIT control succeeds, while the native executable aborts before Build<string> returns.

    • Failing test: dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.NativeAotRepro/Program.cs
    • Files examined: dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DeclarativeWorkflowBuilder.cs, dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DeclarativeWorkflowOptions.cs, dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PowerFx/RecalcEngineFactory.cs, dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Microsoft.Agents.AI.Workflows.Declarative.csproj, dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests.csproj
    • Tests run: JIT control repro, NativeAOT linux-x64 publish, published NativeAOT executable
    • Reported version: 1.25.0
    • Current version: 1.25.0
  5. added
    declarativeUsage: [Issues, PRs], Target: declarative agents and workflows
    workflowsUsage: [Issues, PRs], Target: Workflows
    and removed
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Oct 15, 2026
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: .NetdeclarativeUsage: [Issues, PRs], Target: declarative agents and workflowsreproducedUsage: [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