Summary
Both JSON-RPC deserializers accept any runId string and silently coerce invalid values to Guid.Empty instead of rejecting the request.
Evidence
src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/Json.cs:486-511
string runId = json.Bind<string>(jsonElement, JsonRpcStrings.RunId);
_ = Guid.TryParse(runId, out Guid result);
...
return new DiscoverRequestArgs(
RunId: result,
...);
and the same pattern for RunRequestArgs.
src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs:588-610
_ = Guid.TryParse(GetRequiredPropertyFromJson<string>(properties, JsonRpcStrings.RunId), out Guid runId);
...
return new DiscoverRequestArgs(runId, tests, filter);
and the same pattern for RunRequestArgs.
src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs:477-531
uses args.RunId to create the per-request consumer and to emit completion/update messages back to the client.
Why this is a real issue
A malformed client payload such as {"runId":"not-a-guid"} is not rejected as an invalid request. Instead, MTP creates the request with Guid.Empty.
That means request correlation continues with a synthetic run id the client never asked for. Updates and completion notifications are then emitted under Guid.Empty, which makes protocol debugging harder and can collapse multiple malformed requests onto the same identifier.
Suggested resolution
Treat an unparseable runId as a protocol error and reject the request during deserialization (or at least during request validation) instead of converting it to Guid.Empty. Add tests for invalid runId values on both serializer implementations.
Related issues
Summary
Both JSON-RPC deserializers accept any
runIdstring and silently coerce invalid values toGuid.Emptyinstead of rejecting the request.Evidence
src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/Json.cs:486-511RunRequestArgs.src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs:588-610RunRequestArgs.src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs:477-531uses
args.RunIdto create the per-request consumer and to emit completion/update messages back to the client.Why this is a real issue
A malformed client payload such as
{"runId":"not-a-guid"}is not rejected as an invalid request. Instead, MTP creates the request withGuid.Empty.That means request correlation continues with a synthetic run id the client never asked for. Updates and completion notifications are then emitted under
Guid.Empty, which makes protocol debugging harder and can collapse multiple malformed requests onto the same identifier.Suggested resolution
Treat an unparseable
runIdas a protocol error and reject the request during deserialization (or at least during request validation) instead of converting it toGuid.Empty. Add tests for invalidrunIdvalues on both serializer implementations.Related issues