Validation Set
Overview
A Validation Set Logic Block aggregates multiple validations that are evaluated together. Instead of defining many individual Validation blocks, a Validation Set groups related validations into a single, cohesive unit.
Validation Sets are ideal when:
- Multiple validations apply to the same entity or scenario
- Related validations should be managed together
- You need comprehensive validation feedback
- You want control over evaluation behavior (all validations vs. stop on first failure)
How Validation Sets Work
A Validation Set contains multiple validations. When invoked, you can configure the evaluation behavior:
Evaluation Modes
| Mode | Behavior | Use Case |
|---|---|---|
| Evaluate All | All validations are evaluated regardless of failures | Show users all issues at once for comprehensive feedback |
| Stop on First Failure | Evaluation stops when the first validation fails | Fail fast for performance or when subsequent validations depend on earlier ones |
Evaluate All Mode
When configured to evaluate all validations:
- All validations are evaluated (even if some fail)
- Results are aggregated into an overall pass/fail
- Individual results are available for detailed feedback
- Error messages are collected from all failing validations
This mode is ideal for user-facing validation where you want to show all problems at once, rather than making users fix issues one at a time.
Stop on First Failure Mode
When configured to stop on first failure:
- Validations are evaluated in sequence
- Evaluation stops when a validation fails
- Only the first failure is reported
- Remaining validations are not evaluated
This mode is useful when:
- Later validations depend on earlier ones passing
- You want to optimize performance by avoiding unnecessary checks
- The validation order represents a logical sequence of prerequisites
Structure
A Validation Set consists of:
| Component | Description |
|---|---|
| Name | Unique identifier for the validation set |
| Description | What the validation set checks |
| Inputs | Shared data available to all validations |
| Validations | Individual validation rules within the set |
| Evaluation Mode | Evaluate All or Stop on First Failure |
| Outputs | Overall result plus individual validation results |
Validations
Each validation within the set has:
- Validation Name: Identifier for the specific validation
- Condition: Expression that must be true for validity
- Error Message: Message when this validation fails
- Severity: Error (blocks action) or Warning (allows action with notice)
Example: Customer Registration Validation Set
Name: ValidateCustomerRegistration
Evaluation Mode: Evaluate All (show user all issues at once)
Inputs:
FirstName(String)LastName(String)Email(String)Phone(String)DateOfBirth(DateTime)AcceptedTerms(Boolean)
Validations:
| # | Validation Name | Condition | Error Message | Severity |
|---|---|---|---|---|
| 1 | FirstNameRequired | FirstName != null && FirstName != "" | "First name is required" | Error |
| 2 | LastNameRequired | LastName != null && LastName != "" | "Last name is required" | Error |
| 3 | EmailRequired | Email != null && Email != "" | "Email address is required" | Error |
| 4 | EmailFormat | CONTAINS(Email, "@") && CONTAINS(Email, ".") | "Please enter a valid email address" | Error |
| 5 | PhoneFormat | Phone == null || LEN(Phone) >= 10 | "Phone number must be at least 10 digits" | Warning |
| 6 | AgeRequirement | DATEDIFF(DateOfBirth, TODAY()) / 365 >= 18 | "You must be 18 or older to register" | Error |
| 7 | TermsAccepted | AcceptedTerms == true | "You must accept the terms and conditions" | Error |
Outputs:
IsValid(Boolean): True if all Error-severity validations passHasWarnings(Boolean): True if any Warning-severity validations failFailedValidations(List): Names of validations that failedErrorMessages(List): Error messages from failed validations
Evaluation Example:
For inputs: FirstName = "John", LastName = "", Email = "john@email", Phone = "555", DateOfBirth = 2010-01-01, AcceptedTerms = true
| Validation | Result | Message |
|---|---|---|
| FirstNameRequired | ✅ Pass | - |
| LastNameRequired | ❌ Fail | "Last name is required" |
| EmailRequired | ✅ Pass | - |
| EmailFormat | ❌ Fail | "Please enter a valid email address" |
| PhoneFormat | ⚠️ Warn | "Phone number must be at least 10 digits" |
| AgeRequirement | ❌ Fail | "You must be 18 or older to register" |
| TermsAccepted | ✅ Pass | - |
Output:
IsValid = false(3 Error validations failed)HasWarnings = true(1 Warning validation failed)FailedValidations = ["LastNameRequired", "EmailFormat", "AgeRequirement", "PhoneFormat"]ErrorMessages = ["Last name is required", "Please enter a valid email address", "You must be 18 or older to register", "Phone number must be at least 10 digits"]
Example: Invoice Validation Set
Name: ValidateInvoiceForPosting
Evaluation Mode: Stop on First Failure (validations have dependencies)
Inputs:
InvoiceDate(DateTime)DueDate(DateTime)TotalAmount(Money)LineItemsTotal(Money)CustomerStatus(Option Set)HasAttachedPO(Boolean)ApproverName(String)
Validations:
| # | Validation Name | Condition | Error Message | Severity |
|---|---|---|---|---|
| 1 | InvoiceDateValid | InvoiceDate != null && InvoiceDate <= TODAY() | "Invoice date cannot be in the future" | Error |
| 2 | DueDateAfterInvoice | DueDate > InvoiceDate | "Due date must be after invoice date" | Error |
| 3 | AmountPositive | TotalAmount > 0 | "Invoice amount must be greater than zero" | Error |
| 4 | LineItemsMatch | ABS(TotalAmount - LineItemsTotal) < 0.01 | "Total does not match sum of line items" | Error |
| 5 | CustomerActive | CustomerStatus == "Active" | "Cannot invoice inactive customer" | Error |
| 6 | POAttached | TotalAmount < 1000 || HasAttachedPO == true | "Purchase order required for invoices over $1,000" | Error |
| 7 | ApproverAssigned | TotalAmount < 5000 || ApproverName != null | "Approver required for invoices over $5,000" | Warning |
In this example, "Stop on First Failure" is used because validation #2 (DueDateAfterInvoice) depends on validation #1 (InvoiceDateValid) passing—if InvoiceDate is null, comparing DueDate to it would be meaningless.
Best Practices
Group Related Validations
Keep validation sets focused on a single entity or process. Create separate sets for different scenarios:
ValidateCustomerForCreationValidateCustomerForDeactivationValidateCustomerForCreditIncrease
Choose the Right Evaluation Mode
| Scenario | Recommended Mode |
|---|---|
| User input validation | Evaluate All (show all issues) |
| API/integration validation | Stop on First Failure (fail fast) |
| Sequential dependencies | Stop on First Failure |
| Independent checks | Evaluate All |
Use Appropriate Severity
- Error: Must be fixed before proceeding (blocks action)
- Warning: Should be addressed but doesn't block action
Order Validations Logically
Place fundamental validations (required fields, data types) before business rule validations (cross-field checks, policy enforcement). This is especially important when using "Stop on First Failure" mode.
Provide Clear Error Messages
Error messages should:
- Explain what's wrong
- Suggest how to fix it
- Be understandable by end users
❌ Bad: "Validation failed"
✅ Good: "Due date must be at least 30 days after invoice date for international customers"