Logic Apps - Conditional check for null equality works in normal flow but fails unit test with internal server error

Richard Coleman 40 Reputation points
2026-07-14T10:46:21.0533333+00:00

Also posted here:
https://github.com/Azure/logicapps/issues/1548

Describe the Bug

When unit testing a workflow containing a null equality check for an object variable, the test will fail stating an internal server error with no other details.

Plan Type

Local

Steps to Reproduce the Bug or Issue

  1. Create an HTTP workflow with an object variable, and a conditional check for the variable to equal null
  2. Run workflow and observe success
  3. Create a basic unit test to check for success
  4. Observe that the unit test fails

Workflow JSON

{
    "definition": {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "contentVersion": "1.0.0.0",
        "actions": {
            "Initialize_variables": {
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "PossiblyNullObject",
                            "type": "object"
                        }
                    ]
                },
                "runAfter": {}
            },
            "test_Resp": {
                "type": "Response",
                "kind": "Http",
                "inputs": {
                    "statusCode": 200
                },
                "runAfter": {
                    "Condition": [
                        "SUCCEEDED"
                    ]
                },
                "operationOptions": "Asynchronous"
            },
            "Condition": {
                "type": "If",
                "expression": {
                    "and": [
                        {
                            "equals": [
                                "@variables('PossiblyNullObject')",
                                "@null"
                            ]
                        }
                    ]
                },
                "actions": {},
                "else": {
                    "actions": {}
                },
                "runAfter": {
                    "Initialize_variables": [
                        "SUCCEEDED"
                    ]
                }
            }
        },
        "outputs": {},
        "triggers": {
            "test_req": {
                "type": "Request",
                "kind": "Http",
                "inputs": {
                    "method": "GET",
                    "schema": {}
                }
            }
        }
    },
    "kind": "Stateful"
}

Unit Test

[TestMethod]
public async Task Test_PossiblyNullObjectCondition_WorkflowSucceeds()
{
    var triggerMock = new TriggerMock(status: TestWorkflowStatus.Succeeded, name: "test_req", outputs: (MockOutput)null);

    var testRun = await this.TestExecutor.Create()
                .RunWorkflowAsync(testMock: new TestMockDefinition(
                    triggerMock: triggerMock,
                    actionMocks: new Dictionary<string, ActionMock>()))
                .ConfigureAwait(false);

    Assert.IsNotNull(testRun);
    Assert.AreEqual(TestWorkflowStatus.Succeeded, testRun.Status);
}
Azure Logic Apps
Azure Logic Apps

An Azure service that automates the access and use of data across clouds without writing code.

0 comments No comments

Answer accepted by question author
Christos Panagiotidis 3,551 Reputation points
2026-07-14T16:15:03.88+00:00

Hi Richard, since the workflow succeeds in the runtime and only the local unit-test host returns an internal error, this looks like a test-engine expression bug rather than a workflow execution failure. Keep the smallest repro you posted and update the Logic Apps extension/test framework and Functions runtime to the latest matching versions. As a temporary workaround, use empty(variables('PossiblyNullObject')) when empty and null have the same business meaning, or make the test initialize/mock an explicit object/value instead of leaving the object variable without a value. I would keep one integration test against the real runtime as well, because the local test host is not a perfect implementation of every Workflow Definition Language edge case. The GitHub issue plus the extension/runtime versions and test-host logs are the right evidence for the product team.

Was this answer helpful?

1 person found this answer helpful.

Answer accepted by question author
Rakesh Mishra 11,340 Reputation points Microsoft External Staff Moderator
2026-07-14T12:00:10.0233333+00:00

Hi @Richard Coleman ,

Welcome to Microsoft Q&A Portal. Thank you for reaching out and sharing your C# unit test code.

I understand you are experiencing an issue where a conditional check for null equality works as expected during normal runtime execution but fails with an internal server error during local C# unit testing. Based on the test script you provided, the root cause involves a combination of how the C# mock payload is constructed and how the Logic Apps engine evaluates WDL expressions against null literals during unit tests.

1. Why the C# Test Script Fails

In your test script, the trigger output is defined as:

var triggerMock = new TriggerMock(status: TestWorkflowStatus.Succeeded, name: "test_req", outputs: (MockOutput)null);

Passing (MockOutput)null sets the entire trigger output envelope to a C# null reference. When the local test engine runs, any workflow expression attempting to call triggerBody() or access properties via triggerOutputs() will throw an evaluation error (often manifesting as an Internal Server Error or InvalidTemplate) because the root output structure itself is missing from the mock engine's context.

The Fix for C#: Instead of casting C# null as the entire MockOutput, instantiate a new MockOutput object and pass null or an anonymous object with null properties as the content/body of the mock:

// Option A: Mocking an explicitly null body payload
var triggerMock = new TriggerMock(
    status: TestWorkflowStatus.Succeeded, 
    name: "test_req", 
    outputs: new MockOutput(content: null)
);

// Option B: Mocking an object with a null property
var triggerMock = new TriggerMock(
    status: TestWorkflowStatus.Succeeded, 
    name: "test_req", 
    outputs: new MockOutput(content: new { customerEmail = (string)null })
);
2. Why the Workflow Definition Also Needs Updating

Even with a valid MockOutput, using direct equality checks like @equals(triggerBody()?['property'], null) can still fail in local unit test execution.

  • Live Cloud Runtime: The engine performs implicit type coercion, often converting null references in string-interpolated expressions to empty strings ("").
  • Local Test Engine: Evaluates expressions strictly against the mock payload without implicit coercion, causing direct comparisons against @null to fail when property navigation resolves to undefined.

To make your condition robust across both live execution and local C# unit tests, replace direct null comparisons with the coalesce() or empty() functions.

References

From the Azure Logic Apps Workflow Definition Language / Function Reference:

"coalesce: Return the first non-null value from one or more parameters. Empty strings, empty arrays, and empty objects are not null."

From the Schema reference for workflow actions and triggers / Function Reference:

"empty: Check whether a collection is empty. Return true if the collection is empty, or return false if not empty."

How to Rewrite Your Workflow Condition

Instead of your current condition:

@equals(triggerBody()?['someProperty'], null) 

Use coalesce() to safely intercept any null or missing values and provide a fallback string for comparison:

@equals(coalesce(triggerBody()?['someProperty'], 'NULL_FALLBACK'), 'NULL_FALLBACK')

By combining the coalesce() expression in your JSON definition with a valid new MockOutput(...) instantiation in your C# test script, your workflow will execute cleanly without internal server errors.

Please let me know if this resolves your issue.

Was this answer helpful?

1 person found this answer helpful.

0 additional answers

Sort by: Oldest

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.