Skip to content

.NET: fix(dotnet): parse declarative workflow formulas and values with InvariantCulture - #10069

Open
Prognosticate X (Prognosticate-X) wants to merge 2 commits into
microsoft:mainfrom
Prognosticate-X:fix/declarative-workflow-culture
Open

Prognosticate X (Prognosticate-X) wants to merge 2 commits into
microsoft:mainfrom
Prognosticate-X:fix/declarative-workflow-culture

Conversation

@Prognosticate-X

Copy link
Copy Markdown
Contributor

Motivation & Context

In .NET declarative workflows (Microsoft.Agents.AI.Workflows.Declarative), expressions and values were parsed using the host process's current culture (CultureInfo.CurrentCulture). On host systems configured with cultures where , is used as the decimal separator (such as de-DE or fr-FR):

  1. PowerFx expressions like =Max(1, 2) failed to parse because , was treated as a decimal separator instead of an argument delimiter.
  2. ObjectExtensions.ConvertType parsed strings like "3.14" using default culture, parsing "3.14" as 314 on de-DE or failing with FormatException on fr-FR.
  3. Converting numbers back to string in ConvertType produced localized strings (e.g. "3,14").

Declarative workflows defined in YAML must produce identical, consistent behavior regardless of host locale, matching the behavior of the Python SDK package.

Fixes #10033

Description & Review Guide

  • What are the major changes?

    • In WorkflowExpressionEngine.cs: explicitly set ParserOptions.Culture = CultureInfo.InvariantCulture when initializing the engine options so PowerFx parses formulas using invariant culture.
    • In TemplateExtensions.cs: pass ParserOptions with CultureInfo.InvariantCulture to engine.Eval(...).
    • In ObjectExtensions.cs: pass CultureInfo.InvariantCulture to int.Parse, long.Parse, decimal.Parse, double.Parse, DateTime.Parse, and TimeSpan.Parse. When converting IFormattable / DateTime / TimeSpan to string in ConvertToString, use CultureInfo.InvariantCulture.
    • Added unit tests in WorkflowExpressionEngineTests.cs, ObjectExtensionsTests.cs, and DeclarativeWorkflowTest.cs testing formula evaluation, type conversion, and declarative workflow execution under de-DE and fr-FR cultures.
  • What is the impact of these changes?

    • Declarative workflows now parse formulas and convert numeric/temporal types identically across all cultures without breaking changes.
  • What do you want reviewers to focus on?

    • Consistency of CultureInfo.InvariantCulture usage across PowerFx parser options and ConvertType.

Related Issue

Fixes #10033

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: Analysis of culture-dependent parsing paths and drafting unit tests for de-DE and fr-FR host locales.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The invariant-culture fix lacks a regression test directly exercising RecalcEngine.Format under de-DE or fr-FR, so existing tests would still pass if the fix were removed.

1 open issue
What changed in this PR

This PR addresses #10033 by making .NET declarative workflow formula parsing and type conversions independent of the host culture.

Changes:

  • Sets invariant culture for Power Fx parsing in the expression engine and template extension.
  • Uses invariant culture for numeric and temporal parsing and formattable string conversion.
  • Adds de-DE and fr-FR regression tests for expressions, conversions, and workflow execution.
File Description
dotnet/​tests/​Microsoft.Agents.AI.Workflows.Declarative.UnitTests/​PowerFx/​WorkflowExpressionEngineTests.cs Tests formula parsing under German and French cultures.
dotnet/​tests/​Microsoft.Agents.AI.Workflows.Declarative.UnitTests/​Extensions/​ObjectExtensionsTests.cs Tests invariant numeric parsing and string conversion.
dotnet/​tests/​Microsoft.Agents.AI.Workflows.Declarative.UnitTests/​DeclarativeWorkflowTest.cs Tests workflow execution and numeric state across cultures.
dotnet/​src/​Microsoft.Agents.AI.Workflows.Declarative/​PowerFx/​WorkflowExpressionEngine.cs Configures invariant parsing while preserving side-effect settings.
dotnet/​src/​Microsoft.Agents.AI.Workflows.Declarative/​Extensions/​TemplateExtensions.cs Passes invariant parser options to template evaluation.
dotnet/​src/​Microsoft.Agents.AI.Workflows.Declarative/​Extensions/​ObjectExtensions.cs Makes supported parsing and formatting conversions culture-independent.

Review effort: Balanced

if (expressionSegment.Expression.ExpressionText is not null)
{
return engine.Eval(expressionSegment.Expression.ExpressionText).Format();
return engine.Eval(expressionSegment.Expression.ExpressionText, options: options).Format();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added regression tests in TemplateExtensionsTests.cs (both PowerFx and Extensions test suites) exercising RecalcEngine.Format with Max(1, 2) under de-DE and fr-FR host locales. Thanks for the review!

This branch was successfully deployed

1 active deployment
github-app-auth — 461cb19f Deployed Nov 4, 2026 by Prognosticate-X via add_label #27053
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Usage: [Issues, PRs], Target: .Net workflows Usage: [Issues, PRs], Target: Workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: [Bug]: Declarative workflows fail or give wrong values on de-DE and fr-FR hosts

2 participants