Describe the bug
CommandResponse can represent contradictory state because its status, results, and TelemetryFailureMessage are independently mutable. The telemetry pipeline currently records TelemetryFailureMessage only when response.Status is outside the 2xx range.
If command code catches an exception or encounters another failure, populates TelemetryFailureMessage, but accidentally leaves the default success status, the response becomes a "task failed successfully": the failure is reported as success and the diagnostic telemetry message is silently ignored.
This was identified in the review of #3426: #3426 (comment)
Expected behavior
Contradictory CommandResponse state should be prevented or detected. A command should not be able to return a successful status together with failure-only telemetry without a clear signal.
Consider introducing construction APIs that encode valid outcomes, such as CommandResponse.FromSuccess(...), CommandResponse.FromException(...), and CommandResponse.FromNonExceptionFailure(...), and/or validation that rejects inconsistent combinations. If compatibility prevents enforcing invariants immediately, emitting TelemetryFailureMessage regardless of status could provide interim detection for incorrectly classified failures.
Actual behavior
CommandResponse defaults to HTTP 200 and exposes mutable properties. A command can set TelemetryFailureMessage while leaving Status successful. The response is treated as successful and the telemetry failure message is not emitted.
Reproduction Steps
- Implement a command that returns its default
CommandResponse.
- Simulate a failure path that sets
context.Response.TelemetryFailureMessage but does not update context.Response.Status.
- Return the response.
- Observe that the command result has a successful status and
ToolFailureMessage is absent from telemetry.
Environment
Shared Microsoft.Mcp.Core command response and telemetry pipeline. Observed while reviewing PR #3426.
Describe the bug
CommandResponsecan represent contradictory state because its status, results, andTelemetryFailureMessageare independently mutable. The telemetry pipeline currently recordsTelemetryFailureMessageonly whenresponse.Statusis outside the 2xx range.If command code catches an exception or encounters another failure, populates
TelemetryFailureMessage, but accidentally leaves the default success status, the response becomes a "task failed successfully": the failure is reported as success and the diagnostic telemetry message is silently ignored.This was identified in the review of #3426: #3426 (comment)
Expected behavior
Contradictory
CommandResponsestate should be prevented or detected. A command should not be able to return a successful status together with failure-only telemetry without a clear signal.Consider introducing construction APIs that encode valid outcomes, such as
CommandResponse.FromSuccess(...),CommandResponse.FromException(...), andCommandResponse.FromNonExceptionFailure(...), and/or validation that rejects inconsistent combinations. If compatibility prevents enforcing invariants immediately, emittingTelemetryFailureMessageregardless of status could provide interim detection for incorrectly classified failures.Actual behavior
CommandResponsedefaults to HTTP 200 and exposes mutable properties. A command can setTelemetryFailureMessagewhile leavingStatussuccessful. The response is treated as successful and the telemetry failure message is not emitted.Reproduction Steps
CommandResponse.context.Response.TelemetryFailureMessagebut does not updatecontext.Response.Status.ToolFailureMessageis absent from telemetry.Environment
Shared
Microsoft.Mcp.Corecommand response and telemetry pipeline. Observed while reviewing PR #3426.