{"record":{"id":"247f654b6a60a1ed","repo":"microsoft/aspire","slug":"at-least-one-process-command-success-exit-code-must-be","errorCode":null,"errorMessage":"At least one process command success exit code must be specified.","messagePattern":"At least one process command success exit code must be specified\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ApplicationModel/ProcessCommandOptions.cs","lineNumber":69,"sourceCode":"    /// </remarks>\n    public bool DisplayImmediately { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets the exit codes that are treated as a successful command invocation when <see cref=\"GetCommandResult\"/> is not specified.\n    /// </summary>\n    /// <remarks>\n    /// The default value is <c>[0]</c>.\n    /// </remarks>\n    public IReadOnlyList<int> SuccessExitCodes\n    {\n        get => _successExitCodes;\n        set\n        {\n            ArgumentNullException.ThrowIfNull(value);\n\n            if (value.Count == 0)\n            {\n                throw new ArgumentException(\"At least one process command success exit code must be specified.\", nameof(value));\n            }\n\n            _successExitCodes = value.ToArray();\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets a callback to be invoked after the process exits to determine the result of the command invocation.\n    /// </summary>\n    /// <remarks>\n    /// When specified, <see cref=\"SuccessExitCodes\"/>, <see cref=\"MaxOutputLineCount\"/>, and <see cref=\"DisplayImmediately\"/>\n    /// are not applied by the default result handling. The callback can use <see cref=\"ProcessCommandResultContext.GetFormattedOutput\"/>\n    /// to format retained process output.\n    /// </remarks>\n    public Func<ProcessCommandResultContext, Task<ExecuteCommandResult>>? GetCommandResult { get; set; }\n}\n\n/// <summary>","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/ProcessCommandOptions.cs#L51-L87","documentation":"The SuccessExitCodes property setter rejects an empty collection. Aspire requires a process command to declare at least one exit code that counts as success, otherwise the host could never determine whether the process succeeded. Throwing in the setter fails fast at model-construction time.","triggerScenarios":"Calling the SuccessExitCodes property setter (directly or via an initializer) on ProcessCommandOptions with an empty list, e.g. new ProcessCommandOptions { SuccessExitCodes = [] } or assigning an emptied List<int>.","commonSituations":"Copy-pasting options object construction without filling success codes; dynamically building the code list from a source that returned no values; clearing the list before assignment.","solutions":["Provide at least one success exit code (typically 0): SuccessExitCodes = new[] { 0 }","Include any additional codes that indicate success for your tool, e.g. new[] { 0, 3010 } for MSI-style restart codes","If building dynamically, guard: if (codes.Count == 0) codes.Add(0); before assigning"],"exampleFix":"// before\nvar options = new ProcessCommandOptions { SuccessExitCodes = [] };\n// after\nvar options = new ProcessCommandOptions { SuccessExitCodes = [0] };","handlingStrategy":"validation","validationCode":"if (options.SuccessExitCodes is null || options.SuccessExitCodes.Count == 0)\n    throw new ArgumentException(\"Provide at least one success exit code, e.g. [0].\");","typeGuard":null,"tryCatchPattern":"try { options.SuccessExitCodes = codes; } catch (ArgumentException ex) { /* supply default [0] */ }","preventionTips":["Always initialize SuccessExitCodes with at least code 0","Never assign a dynamically built list without a count check"],"tags":["process","argument-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"}