{"record":{"id":"e0ec7c7d7dc08fac","repo":"microsoft/aspire","slug":"process-command-success-exit-codes-must-contain-at-least-one","errorCode":null,"errorMessage":"Process command success exit codes must contain at least one value.","messagePattern":"Process command success exit codes must contain at least one value\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ResourceBuilderExtensions.cs","lineNumber":3499,"sourceCode":"        return GetDefaultProcessCommandResult(processCommandSpec.ExecutablePath, processResult, commandOptions);\n    }\n\n    internal static ExecuteCommandResult GetDefaultProcessCommandResult(string executablePath, ProcessResult processResult, ProcessCommandOptions commandOptions)\n    {\n        var formattedOutput = processResult.GetFormattedOutput(commandOptions.MaxOutputLineCount);\n        var resultData = string.IsNullOrEmpty(formattedOutput)\n            ? null\n            : new CommandResultData\n            {\n                Value = formattedOutput,\n                Format = CommandResultFormat.Text,\n                DisplayImmediately = commandOptions.DisplayImmediately\n            };\n\n        var successExitCodes = commandOptions.SuccessExitCodes;\n        if (successExitCodes is null || successExitCodes.Count == 0)\n        {\n            throw new InvalidOperationException(\"Process command success exit codes must contain at least one value.\");\n        }\n\n        if (successExitCodes.Contains(processResult.ExitCode))\n        {\n            return resultData is null\n                ? CommandResults.Success()\n                : new ExecuteCommandResult { Success = true, Data = resultData };\n        }\n\n        var message = $\"Command '{executablePath}' exited with code {processResult.ExitCode}, which is not in the configured success exit codes [{string.Join(\", \", successExitCodes)}].\";\n\n        return resultData is null\n            ? CommandResults.Failure(message)\n            : CommandResults.Failure(message, resultData);\n    }\n\n#pragma warning restore ASPIREPROCESSCOMMAND001\n","sourceCodeStart":3481,"sourceCodeEnd":3517,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ResourceBuilderExtensions.cs#L3481-L3517","documentation":"When a process command executes, Aspire decides success by checking the process exit code against the configured SuccessExitCodes collection. If that collection is null or empty no exit code could ever be considered successful, so Aspire throws InvalidOperationException instead of executing a command that can never succeed.","triggerScenarios":"Configuring a process command (e.g. WithCommand with startCommandOptions or a custom success-exit-codes callback path) where CommandOptions.SuccessExitCodes is left null or set to an empty set/array.","commonSituations":"Building success exit codes from a list populated conditionally at runtime so it ends up empty; passing an empty HashSet/array by mistake; forgetting the default is non-empty but supplying an explicit empty collection.","solutions":["Populate SuccessExitCodes with at least one code, typically new[] { 0 } or the process's documented success codes","If building the set dynamically, validate it is non-empty (or fall back to [0]) before assigning","Remove the explicit empty SuccessExitCodes assignment to let the default apply"],"exampleFix":"// before\noptions.SuccessExitCodes = [];\n// after\noptions.SuccessExitCodes = [0];","handlingStrategy":"validation","validationCode":"if (options.SuccessExitCodes is null || options.SuccessExitCodes.Count == 0)\n    options.SuccessExitCodes = [0];","typeGuard":"bool HasSuccessCodes(ICollection<int>? codes) => codes is { Count: > 0 };","tryCatchPattern":"try { /* configure command */ }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"success exit codes\")) { /* supply default codes and retry */ }","preventionTips":["Always initialize SuccessExitCodes with at least the standard code 0","Validate dynamically-built exit-code sets before assignment"],"tags":["process","exit-codes","validation","aspire-hosting"],"backgroundTag":"empty-required-field","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"}