Study guide

9.4 Validating Mule Events with the Validation Module

Salesforce Certified MuleSoft Developer I Exam

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Creating Application Networks & API-Led Connectivity

1.1 The IT Delivery Gap & API-Led Connectivity Architecture 1.2 Application Network Foundations & Center for Enablement (C4E) 1.3 Anypoint Platform Architecture & Core Components

2 Chapter 2: Designing APIs with RAML & API Designer

2.1 RAML 1.0 Fundamentals, Data Types & Resource Hierarchy 2.2 Reusable API Fragments, ResourceTypes & Traits 2.3 API Mocking Service, Documentation & Anypoint Exchange Publishing

3 Chapter 3: Accessing and Modifying Mule Events

3.1 Mule 4 Event Architecture: Message, Payload, Attributes & Variables 3.2 Flow Variable Management & Target Variables Pattern 3.3 Accessing Event Metadata, Inbound Attributes & Context Properties

4 Chapter 4: Structuring Mule Applications

4.1 Modular Flow Composition: Flows, Subflows & Private Flows 4.2 Configuration Property Files & Environment Management 4.3 Secure Properties Tool, Encryption & Maven Project Packaging

5 Chapter 5: Building API Implementation Interfaces

5.1 APIkit Scaffolding, Router Configuration & Interface Generation 5.2 HTTP Listener Configuration, Path Matching & Query/URI Parameters 5.3 Interface vs. Implementation Separation & Backend Flow Wiring

6 Chapter 6: Using Connectors & External Systems

6.1 Database Connector: Select, Insert, Update, Stored Procedures & Watermarking 6.2 HTTP Request Connector: Headers, Query Params, Response Timeouts & Target Variables 6.3 Salesforce Connector, JMS Messaging & File/FTP Connectors

7 Chapter 7: Processing Records & Batch Integration

7.1 For Each Scope: Payload Iteration, Batch Size & Streaming Data 7.2 Batch Job Architecture: Input, Process, and Complete Phases 7.3 Batch Step Accept Expression, Failure Handling & Batch Aggregator 7.4 Object Store: Persisting Data Between Flow Executions

8 Chapter 8: Transforming Data with DataWeave 2.0

8.1 DataWeave 2.0 Syntax, Type System & Selectors 8.2 Core Functions: map, filter, pluck, reduce, groupBy & orderBy 8.3 Custom Functions, Format Transformations & Type Coercion 8.4 Calling Mule Flows from DataWeave & Reusing DataWeave Modules

9 Chapter 9: Routing Events & Flow Control

9.1 Choice Router: Conditional Expressions & Default Routing 9.2 Scatter-Gather Router: Parallel Execution, Aggregation & Error Traps 9.3 Async Scope, Round Robin & First Successful Routing 9.4 Validating Mule Events with the Validation Module

10 Chapter 10: Handling Errors & Exception Management

10.1 Mule 4 Error Object Hierarchy & Custom Error Types 10.2 On-Error Continue vs. On-Error Propagate Mechanisms 10.3 Try Scope Exception Isolation & Global Error Handling Strategies

11 Chapter 11: Debugging and Troubleshooting Mule Applications

11.1 Logger Configuration, Categories & Thread/Context Diagnostics 11.2 Anypoint Studio Debugger: Breakpoints, Expression Watches & Step-Through 11.3 MUnit 2.x Testing: Unit Tests, Mocking Connectors & Assertions

12 Chapter 12: Deploying and Managing APIs and Integrations

12.1 CloudHub 1.0 & 2.0 Architecture: Workers, vCores & Clustering 12.2 Runtime Manager: Application Management, Alerts, Insights & Logs 12.3 API Manager: Auto-Discovery, API Gateway, SLA Tiers & Standard Policies

9.4 Validating Mule Events with the Validation Module

Key Takeaways Explain This Topic AI

The Validation module raises a typed VALIDATION:* error when a value fails a check, converting silent bad data into an error the flow can handle.

Each validator has its own error type — is-true and is-false raise VALIDATION:INVALID_BOOLEAN, matches-regex raises VALIDATION:MISMATCH, is-not-null raises VALIDATION:NULL.

The validation:all scope runs every nested validator and reports one summarizing VALIDATION:MULTIPLE error instead of stopping at the first failure.

Every validator accepts an optional message parameter for a business-readable failure message, plus error mappings to re-map its error type.

Validators are for rejecting invalid data; a Choice router is for sending valid data down different paths — the exam tests that distinction directly.

Last updated: August 2026

Validating Mule Events with the Validation Module

The Routing Events domain of the Salesforce Certified MuleSoft Developer I blueprint lists three objectives, and only two of them are routers. The third — apply correct processors/syntax to validate Mule events, and predict outcomes — is about the Validation module , a set of small components that assert something about the event and raise a typed error when the assertion fails. It sits in the routing domain because validation and routing are the two ways a flow reacts to message content: routing sends good data down different paths, validation stops bad data from travelling at all.

1. What a Validator Actually Does

A validator has exactly two outcomes. If the condition holds, the event passes through completely unchanged — payload, attributes, and variables are untouched, and the next processor runs. If the condition fails, the validator raises a typed error and normal Mule error handling takes over. +-----------------------------------------------------------------------------------------+

  • | VALIDATOR EXECUTION OUTCOMES |
  • | |
  • | [ Mule Event ] ---> <validation:is-number value="#[payload.qty]"/> |
  • | | |
  • | +-------------------+-------------------+ |
  • | | | |
  • | (condition true) (condition false) |
  • | | | |
  • | v v |
  • | [ Event continues UNCHANGED ] [ VALIDATION:INVALID_NUMBER raised ] |
  • | payload/attributes/vars intact --> matching on-error-* scope handles it |
  • +-----------------------------------------------------------------------------------------+

That "unchanged" behavior matters for prediction questions. A validator never sets the payload to true , never wraps the payload in a result object, and never returns a Boolean into the flow. If a question shows a validator followed by a Logger printing #[payload] , the Logger prints whatever the payload was before the validator.

2. The Validator Catalogue and Their Error Types

Every validator declares its own error type, which is what lets an error handler respond differently to each kind of bad input.

  • Validator XML element Error type raised on failure
  • Is True <validation:is-true> VALIDATION:INVALID_BOOLEAN
  • Is False <validation:is-false> VALIDATION:INVALID_BOOLEAN
  • Is Number <validation:is-number> VALIDATION:INVALID_NUMBER
  • Is Email <validation:is-email> VALIDATION:INVALID_EMAIL
  • Is URL <validation:is-url> VALIDATION:INVALID_URL
  • Is Time <validation:is-time> VALIDATION:INVALID_TIME
  • Is IP <validation:is-ip> VALIDATION:INVALID_IP
  • Is Not Null <validation:is-not-null> VALIDATION:NULL
  • Is Null <validation:is-null> VALIDATION:NOT_NULL
  • Is Not Blank String <validation:is-not-blank-string> VALIDATION:BLANK_STRING
  • Is Blank String <validation:is-blank-string> VALIDATION:NOT_BLANK_STRING
  • Is Not Empty Collection <validation:is-not-empty-collection> VALIDATION:EMPTY_COLLECTION
  • Is Empty Collection <validation:is-empty-collection> VALIDATION:NOT_EMPTY_COLLECTION
  • Matches Regex <validation:matches-regex> VALIDATION:MISMATCH
  • Validate Size <validation:validate-size> VALIDATION:INVALID_SIZE

Is Elapsed / Is Not Elapsed <validation:is-elapsed> / <validation:is-not-elapsed> VALIDATION:NOT_ELAPSED_TIME / VALIDATION:ELAPSED_TIME

Notice the two naming inversions that trip candidates up: is-not-null fails with VALIDATION:NULL (the error names the problem , not the check), and matches-regex fails with VALIDATION:MISMATCH rather than an "INVALID_REGEX" type. <flow name="create-customer-flow">

<http:listener config-ref="HTTP_Listener_config" path="/customers" doc:name="Listener"/>

  • <validation:is-not-blank-string value="#[payload.lastName]"
  • message="lastName is required"
  • doc:name="Require Last Name"/>
  • <validation:is-email email="#[payload.email]"
  • message="#['Not a valid email address: ' ++ (payload.email default 'null')]"
  • doc:name="Validate Email"/>
  • <validation:matches-regex value="#[payload.postalCode]"
  • regex="^\d{5}(-\d{4})?$"
  • message="Postal code must be 5 or 9 digits"
  • doc:name="Validate Postal Code"/>
  • <db:insert config-ref="Database_Config" doc:name="Insert Customer">
  • <db:sql>INSERT INTO customers (last_name, email) VALUES (:ln, :em)</db:sql>
  • <db:input-parameters><![CDATA[#[{'ln': payload.lastName, 'em': payload.email}]]]></db:input-parameters>
  • </db:insert>

<error-handler>

<on-error-propagate type="VALIDATION:INVALID_EMAIL, VALIDATION:MISMATCH, VALIDATION:BLANK_STRING" doc:name="Bad Request">

  • <set-variable variableName="httpStatus" value="400" doc:name="Set 400"/>
  • <set-payload value="#[{ error: 'BAD_REQUEST', detail: error.description }]" doc:name="Error Body"/>
  • </on-error-propagate>
  • </error-handler>
  • </flow>

That error handler is the point of typed validation errors: three different validator failures all map to a single HTTP 400 , while a DB:CONNECTIVITY error further down would not match and would fall through to a different handler and a 500.

3. Fail Fast vs. Collect Everything: all and any

By default, validators are sequential and fail fast — the first failure raises and the rest never execute. A client submitting a form with three bad fields would have to fix them one round trip at a time. The <validation:all> scope solves that: it runs every nested validator and reports one aggregated error. <validation:all doc:name="Validate All Fields">

  • <validation:is-not-blank-string value="#[payload.firstName]" message="firstName is required"/>
  • <validation:is-not-blank-string value="#[payload.lastName]" message="lastName is required"/>
  • <validation:is-email email="#[payload.email]" message="email is invalid"/>
  • <validation:is-number value="#[payload.age]" message="age must be numeric"/>
  • </validation:all>
  • Scope Behavior Error type raised
  • Sequential validators Stops at the first failure The specific type of the validator that failed
  • <validation:all> Runs all nested validators, then reports the combined result VALIDATION:MULTIPLE

<validation:any> Succeeds if at least one nested validator passes VALIDATION:MULTIPLE only when all of them fail

Important

all Always Raises VALIDATION:MULTIPLE Inside an <validation:all> scope the individual types are collapsed: no matter which nested validators failed or how many, the scope reports VALIDATION:MULTIPLE . An error handler written for VALIDATION:INVALID_EMAIL will therefore not catch a failure that occurred inside an all scope. The individual messages are still available through the error description.

4. Customizing the Failure

Two optional parameters are available on every validator:

message — a business-readable string (or DataWeave expression) that becomes the error description, replacing the generic technical text. This is what an API returns to its consumer.

Error mappings — re-map the raised type to a domain type, so a validation failure can surface as, for example, ORDER:INVALID_QUANTITY and be handled alongside other order errors. <validation:is-number value="#[payload.quantity]" message="quantity must be numeric" doc:name="Check Quantity">

  • <error-mapping sourceType="VALIDATION:INVALID_NUMBER" targetType="ORDER:INVALID_QUANTITY"/>
  • </validation:is-number>
  • Validators as DataWeave Functions

The module also exposes its checks as DataWeave functions using the ExtensionName::functionName form, which is useful inside a router condition where you want a Boolean rather than an error: #[Validation::isEmail(payload.email)]

  • #[Validation::isNumber(payload.quantity)]
  • 5. Choosing Between Validator, Choice, and raise-error
  • Requirement Correct component
  • Reject the message when a field is missing or malformed Validation module validator
  • Send valid messages down different processing paths <choice> router

Stop on a business rule with no matching validator (e.g. "item is out of stock") <raise-error type="INVENTORY:OUT_OF_STOCK"/>

Report every field problem in one response <validation:all> scope

Tip

The Empty <otherwise> Anti-Pattern A Choice router whose <otherwise> branch is empty does not stop or reject anything — the event simply passes through unchanged, and the invalid message continues downstream. When a scenario says execution must halt for invalid input, an empty <otherwise> is always the wrong answer; a validator or <raise-error> is the right one.

Warning

Validators Raise Errors — Plan the Handler Because a failed validator raises rather than returns, a flow with no matching on-error-* scope propagates a validation failure all the way to the HTTP Listener, which returns a 500 under default settings. An API that should answer 400 Bad Request must map the VALIDATION:* types explicitly, as in the example above.