{"record":{"id":"ee1144e3865c2c1d","repo":"elsa-workflows/elsa-core","slug":"priority-must-be-between-0-and-100","errorCode":null,"errorMessage":"Priority must be between 0 and 100.","messagePattern":"Priority must be between 0 and 100\\.","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.UserTasks/Models/UserTaskModels.cs","lineNumber":215,"sourceCode":"    public bool EnableTimeoutOutcome { get; init; }\n    public bool EnableCancellationOutcome { get; init; }\n\n    public UserTaskDefinitionSnapshot Normalize()\n    {\n        var actions = Actions.Count == 0\n            ? [new UserTaskAction(\"Complete\", \"Complete\")]\n            : Actions;\n\n        if (string.IsNullOrWhiteSpace(Title))\n            throw new ArgumentException(\"A User Task title is required.\", nameof(Title));\n        if (actions.Any(x => string.IsNullOrWhiteSpace(x.Key) || string.IsNullOrWhiteSpace(x.Label)))\n            throw new ArgumentException(\"User Task action keys and labels are required.\", nameof(Actions));\n        if (actions.Any(x => string.Equals(x.Key, \"Timeout\", StringComparison.OrdinalIgnoreCase) || string.Equals(x.Key, \"Cancelled\", StringComparison.OrdinalIgnoreCase)))\n            throw new ArgumentException(\"Timeout and Cancelled are reserved User Task action keys.\");\n        if (actions.Select(x => x.Key).Distinct(StringComparer.OrdinalIgnoreCase).Count() != actions.Count)\n            throw new ArgumentException(\"User Task action keys must be unique.\");\n        if (Priority is < 0 or > 100)\n            throw new ArgumentOutOfRangeException(nameof(Priority), \"Priority must be between 0 and 100.\");\n        if (Invitations.Any(x => string.IsNullOrWhiteSpace(x.VerifierName) || x.AllowedActions.Count == 0 || x.AllowedActions.Any(string.IsNullOrWhiteSpace)))\n            throw new ArgumentException(\"Invitation verifier names and allowed actions are required.\", nameof(Invitations));\n        if (Invitations.Any(invitation => invitation.AllowedActions.Any(allowed => !actions.Any(action => string.Equals(action.Key, allowed, StringComparison.OrdinalIgnoreCase)))))\n            throw new ArgumentException(\"Invitation actions must be configured User Task actions.\", nameof(Invitations));\n\n        return this with { Actions = actions };\n    }\n}\n\npublic sealed class UserTask\n{\n    public string Id { get; set; } = Guid.NewGuid().ToString(\"N\");\n    public string TenantId { get; set; } = \"\";\n    public string WorkflowDefinitionId { get; set; } = \"\";\n    public string? WorkflowDefinitionName { get; set; }\n    public int? WorkflowDefinitionVersion { get; set; }\n    public string WorkflowInstanceId { get; set; } = \"\";\n    /// <summary>A safe, host-authored instance reference (correlation ID or instance name). Never a bookmark or token.</summary>","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.UserTasks/Models/UserTaskModels.cs#L197-L233","documentation":"Normalize() validates that the UserTaskDefinition's Priority is within the inclusive range 0..100 and throws ArgumentOutOfRangeException when it is outside. Priority drives ordering of tasks in queues/UX, so out-of-range values are rejected at materialization time.","triggerScenarios":"Constructing or deserializing a UserTaskDefinition with Priority set to e.g. 150, -1, int.MaxValue, or a default of 0 intentionally misread; calling Normalize() (directly or through DefaultUserTaskManager.ProjectAsync) then throws.","commonSituations":"UI sliders that allow values beyond 100; configurations importing priority from another system on a 1–10 scale misinterpreted as 0–100; uninitialized fields set to -1 as a sentinel.","solutions":["Clamp the priority before normalizing: Math.Clamp(priority, 0, 100).","Fix the source value/scale — map the external scale into 0–100.","If you need a 'no priority' state, use null rather than a sentinel like -1 if the property is nullable."],"exampleFix":"// before\ndefinition.Priority = externalPriority; // external scale 1-10\n// after\ndefinition.Priority = Math.Clamp(externalPriority * 10, 0, 100);","handlingStrategy":"validation","validationCode":"if (definition.Priority is < 0 or > 100)\n    definition.Priority = Math.Clamp(definition.Priority, 0, 100);","typeGuard":null,"tryCatchPattern":"try { definition = definition.Normalize(); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == nameof(UserTaskDefinition.Priority)) { /* clamp and retry */ }","preventionTips":["Clamp or validate priority in the setter/UI before it reaches the definition","Document the 0–100 contract wherever definitions are authored","Add property-based tests covering boundary values 0, 100, -1, 101"],"tags":["validation","priority","range"],"backgroundTag":"value-out-of-range","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}