diff --git a/python/packages/declarative/agent_framework_declarative/_workflows/_declarative_base.py b/python/packages/declarative/agent_framework_declarative/_workflows/_declarative_base.py index 687dad096b..01a68e6a8e 100644 --- a/python/packages/declarative/agent_framework_declarative/_workflows/_declarative_base.py +++ b/python/packages/declarative/agent_framework_declarative/_workflows/_declarative_base.py @@ -388,11 +388,15 @@ def eval(self, expression: str) -> Any: from System.Globalization import CultureInfo original_culture = CultureInfo.CurrentCulture - CultureInfo.CurrentCulture = CultureInfo("en-US") + original_ui_culture = CultureInfo.CurrentUICulture + en_us_culture = CultureInfo("en-US") + CultureInfo.CurrentCulture = en_us_culture + CultureInfo.CurrentUICulture = en_us_culture try: return engine.eval(formula, symbols=symbols) finally: CultureInfo.CurrentCulture = original_culture + CultureInfo.CurrentUICulture = original_ui_culture except ValueError as e: error_msg = str(e) # Handle undefined variable errors gracefully by returning None diff --git a/python/packages/declarative/tests/test_powerfx_yaml_compatibility.py b/python/packages/declarative/tests/test_powerfx_yaml_compatibility.py index 9591dc05cb..8ea3c3af57 100644 --- a/python/packages/declarative/tests/test_powerfx_yaml_compatibility.py +++ b/python/packages/declarative/tests/test_powerfx_yaml_compatibility.py @@ -493,6 +493,31 @@ async def test_undefined_nested_variable_returns_none(self, mock_state): result = state.eval("=Local.Something.Nested.Deep") assert result is None + async def test_undefined_variable_returns_none_with_non_english_ui_culture(self, mock_state): + """Test that undefined variables return None even when CurrentUICulture is non-English. + + Regression test for #4321: on non-English systems, CurrentUICulture causes + PowerFx to emit localized error messages that don't match the English + string guards ("isn't recognized", "Name isn't valid"), crashing the workflow. + The fix sets CurrentUICulture to en-US alongside CurrentCulture before eval. + """ + from System.Globalization import CultureInfo + + state = DeclarativeWorkflowState(mock_state) + state.initialize() + + # Simulate a non-English UI culture (e.g. Italian) + original_ui_culture = CultureInfo.CurrentUICulture + CultureInfo.CurrentUICulture = CultureInfo("it-IT") + try: + # Should return None, not raise ValueError with Italian error text + result = state.eval("=Local.StatusConversationId") + assert result is None + # Verify the production code restored CurrentUICulture after eval + assert str(CultureInfo.CurrentUICulture) == str(CultureInfo("it-IT")) + finally: + CultureInfo.CurrentUICulture = original_ui_culture + class TestStringInterpolation: """Test string interpolation patterns."""