{"record":{"id":"c43ba9c11185d63c","repo":"microsoft/aspire","slug":"a-validation-message-must-be-provided-for-a-failed","errorCode":null,"errorMessage":"A validation message must be provided for a failed validation.","messagePattern":"A validation message must be provided for a failed validation\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ApplicationModel/RequiredCommandValidationResult.cs","lineNumber":19,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace Aspire.Hosting.ApplicationModel;\n\n/// <summary>\n/// Represents the result of validating a required command.\n/// </summary>\n[Experimental(\"ASPIRECOMMAND001\", UrlFormat = \"https://aka.ms/aspire/diagnostics/{0}\")]\n[AspireExport(ExposeProperties = true)]\npublic sealed class RequiredCommandValidationResult\n{\n    private RequiredCommandValidationResult(bool isValid, string? validationMessage)\n    {\n        if (!isValid && validationMessage is null)\n        {\n            throw new ArgumentException(\"A validation message must be provided for a failed validation.\", nameof(validationMessage));\n        }\n\n        IsValid = isValid;\n        ValidationMessage = validationMessage;\n    }\n\n    /// <summary>\n    /// Gets a value indicating whether the command validation succeeded.\n    /// </summary>\n    [MemberNotNullWhen(false, nameof(ValidationMessage))]\n    public bool IsValid { get; }\n\n    /// <summary>\n    /// Gets an optional validation message describing why validation failed.\n    /// </summary>\n    public string? ValidationMessage { get; }\n\n    /// <summary>","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/RequiredCommandValidationResult.cs#L1-L37","documentation":"RequiredCommandValidationResult carries the outcome of a required-command validation: IsValid plus an optional ValidationMessage. The private constructor enforces the invariant that a failed validation must always include a human-readable message, throwing ArgumentException when isValid is false and validationMessage is null. This guarantees the dashboard/interaction UI always has something to show the user when a required command is missing or fails.","triggerScenarios":"Creating an instance via its factory methods (e.g. RequiredCommandValidationResult.Fail(null) or the private constructor with isValid:false and validationMessage:null) — calling the failure factory without a message.","commonSituations":"Custom ValidateRequiredCommand implementations that build the failure message in a variable which ends up null (e.g. a lookup of the command's error text returned null); passing an uninitialized string field to Fail/invalid-result factory methods.","solutions":["Always pass a non-null message when creating a failed validation result, e.g. return RequiredCommandValidationResult.Fail(\"dotnet ef was not found on PATH.\");","If the message is computed, coalesce it: var msg = computedMessage ?? \"Required command validation failed.\";","If the command actually validated fine, create the success result (isValid: true) instead, which permits a null message."],"exampleFix":"// before\nreturn RequiredCommandValidationResult.Fail(missingCommandError); // missingCommandError is null\n// after\nreturn RequiredCommandValidationResult.Fail($\"Required command '{commandName}' failed validation: {missingCommandError ?? \"not found\"}\");","handlingStrategy":"validation","validationCode":"if (!isValid && string.IsNullOrEmpty(validationMessage))\n{\n    validationMessage = \"Required command validation failed.\"; // supply default before constructing result\n}","typeGuard":"bool IsValidFailure(RequiredCommandValidationResult r) => r is { IsValid: true } || r.ValidationMessage is not null;","tryCatchPattern":"try\n{\n    var result = RequiredCommandValidationResult.Fail(message);\n}\ncatch (ArgumentException ex) when (ex.ParamName == \"validationMessage\")\n{\n    result = RequiredCommandValidationResult.Fail(\"Required command validation failed.\");\n}","preventionTips":["Coalesce computed messages with a default string before calling Fail.","Use the factory methods rather than the private constructor so the invariant is checked in one place.","Only pass null messages for successful (isValid: true) results."],"tags":["validation","invariant","argument"],"backgroundTag":"schema-validation-failed","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}