Skip to content

[copilot-finds] Bug: TestOrchestrationClient serializes null values differently from TaskHubGrpcClient #186

@github-actions

Description

@github-actions

Problem

TestOrchestrationClient.raiseOrchestrationEvent and terminateOrchestration handle null data differently from the real TaskHubGrpcClient, causing behavioral divergence between test and production environments.

File: packages/durabletask-js/src/testing/test-client.ts (lines 95, 103)

Real client behavior (TaskHubGrpcClient)

Both raiseOrchestrationEvent (line 415 of client.ts) and terminateOrchestration (line 485) unconditionally call JSON.stringify(data):

const i = new StringValue();
i.setValue(JSON.stringify(data));  // null → "null"
req.setInput(i);

This means even when data is null (the default parameter), the string "null" is stored. When deserialized by the executor, the orchestrator receives null.

Test client behavior (TestOrchestrationClient)

Both methods used a guard that skipped serialization for null:

const encodedData = data !== null ? JSON.stringify(data) : undefined;

When data is null, encodedData becomes undefined, so no input is stored. When deserialized by the executor, the orchestrator receives undefined instead of null.

Root Cause

The conditional data !== null ? JSON.stringify(data) : undefined was intended to avoid serializing "no data," but it conflicts with the real client's behavior of always serializing — including null. The real client treats null as a valid serializable value, not as "absent."

Proposed Fix

Change both methods to unconditionally call JSON.stringify(data), matching the real client:

const encodedData = JSON.stringify(data);

Impact

Severity: Medium — Causes silent behavioral divergence between test and production.

Affected scenarios:

  • Orchestrations that call waitForExternalEvent and check the received value with strict equality (=== null) would get true in production but false in tests.
  • Orchestrations terminated with default output would see null in production but undefined in tests when reading serializedOutput.
  • Any test relying on the in-memory backend to faithfully reproduce production semantics for null event data is unreliable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    copilot-findsFindings from daily automated code review agent

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions