express-validator
semver
>=6.0.0 <8.0.0postconditions29functions14last verified2026-04-16coverage score87%Postconditions — what we check
- validationResult · errors-not-checkederrorWhenvalidationResult() is called but the result is not inspected before using request dataReturnsValidation errors exist but are silently ignored. Invalid input is processed as if valid.Required handlingCaller MUST call validationResult(req) and check isEmpty() or the errors array before using validated fields. Failing to check means invalid input silently passes through. Pattern: const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- validationResult · success-no-errorsinfoWhenAll validation chains passed for the requestReturnsResult object with isEmpty() === trueRequired handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2]
- validationResult · validation-failedinfoWhenOne or more validation chains failed for the requestReturnsResult object with isEmpty() === false. errors.array() returns list of {type, msg, path, location} objects.Required handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2]
- body · validation-errors-silenterrorWhenThe field fails validation (e.g., notEmpty(), isEmail())ReturnsError is added to the request's validation error list. Request processing continues to the next middleware. No HTTP error is sent automatically.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false. Without this check, invalid data silently reaches business logic.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- body · successinfoWhenField passes all validation rulesReturnsNo error is added. Request continues normally.Required handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- check · validation-errors-silenterrorWhenThe field fails validationReturnsError is added to the request's validation error list. Request processing continues.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false. Without this check, invalid data silently reaches business logic.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- check · successinfoWhenField passes all validation rulesReturnsNo error is added. Request continues normally.Required handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- query · validation-errors-silenterrorWhenThe query parameter fails validationReturnsError is added to the request's validation error list. Request processing continues.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- query · successinfoWhenQuery parameter passes all validation rulesReturnsNo error is added. Request continues normally.Required handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- param · validation-errors-silenterrorWhenThe route parameter fails validationReturnsError is added to the request's validation error list. Request processing continues.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- param · successinfoWhenRoute parameter passes all validation rulesReturnsNo error is added. Request continues normally.Required handlingNo action required — use the returned value as needed.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1]
- cookie · cookie-validation-errors-silenterrorWhenThe cookie field fails validation (e.g., notEmpty(), isUUID())ReturnsError is added to the request's validation error list. Request processing continues.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false. Without this check, invalid cookie data silently reaches business logic. Cookie-based auth tokens are a common validation target.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[3]
- cookie · cookie-successinfoWhenCookie field passes all validation rulesReturnsNo error is added. Request continues normally.Required handlingNo action required.costlowin proddegraded serviceusers seedegraded performancevisibilitysilentSources[3]
- header · header-validation-errors-silenterrorWhenThe header field fails validation (e.g., required Authorization header is missing or malformed)ReturnsError is added to the request's validation error list. Request processing continues.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false. Header validation often checks auth tokens or API keys — failure to check means unauthorized requests may reach protected business logic.costhighin prodsilent failureusers seelost datavisibilitysilentSources[3]
- header · header-successinfoWhenHeader field passes all validation rulesReturnsNo error is added. Request continues normally.Required handlingNo action required.costlowin proddegraded serviceusers seedegraded performancevisibilitysilentSources[3]
- checkSchema · checkschema-validation-errors-silenterrorWhenOne or more fields in the schema fail their validation rulesReturnsErrors are added to the request's validation error list. Request processing continues to the next middleware. No HTTP error is sent automatically.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false. checkSchema() is commonly used for complex multi-field forms — failure to check means all field errors are silently ignored and invalid data reaches business logic.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[4]
- checkSchema · checkschema-run-result-not-checkederrorWhencheckSchema chains are invoked with .run(req) but validationResult is not called afterwardReturnsValidation runs but results are discarded. All validated fields pass through to the handler regardless of validity.Required handlingWhen using checkSchema chains programmatically with .run(req), always call validationResult(req) in the route handler afterward. The .run() persists errors to req (dryRun: false by default), so validationResult will see them — but only if called.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[5]
- oneOf · oneof-all-chains-failed-error-not-checkederrorWhenNone of the provided validation chains pass, but validationResult() is not calledReturnsA single AlternativeValidationError (or GroupedAlternativeValidationError) is added to the request with nested errors. Request continues to the route handler, which silently processes the invalid input.Required handlingRoute handler MUST call validationResult(req) and check isEmpty(). With oneOf(), errors are nested under nestedErrors — the alternative error wraps all chain errors. Accessing errors.array() returns the top-level alternative error. Use error.nestedErrors to inspect which alternatives failed and why.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[6]
- oneOf · oneof-nested-errors-not-inspectedwarningWhenvalidationResult() is called and errors exist from oneOf(), but only the top-level error is inspected without examining nestedErrorsReturnsThe top-level AlternativeValidationError is returned. The nestedErrors property contains the actual per-chain failures but is never read, so users receive a generic error message instead of actionable field-level errors.Required handlingFor user-facing error messages, access error.nestedErrors to get per-chain failure details. The errorType option controls structure: 'flat' provides all errors in one array; 'least_errored' shows only the closest-to-passing chain; 'grouped' (default) groups by chain group.costlowin proddegraded serviceusers seedegraded performancevisibilityvisibleSources[6]
- checkExact · checkexact-unknown-fields-not-checkederrorWhenRequest contains fields not covered by any validation chain, but validationResult() is not calledReturnsA UnknownFieldsError with type 'unknown_fields' is added to the request. The unknownFields property lists all unexpected fields. Request continues to the route handler, which may process the unexpected data.Required handlingRoute handler MUST call validationResult(req) and return an error response when isEmpty() is false. The UnknownFieldsError has an unknownFields property listing all unexpected fields and their locations. Without this check, mass-assignment attacks succeed — users can submit arbitrary fields that bypass your validation schema.costhighin prodsilent failureusers seelost datavisibilitysilentSources[7]
- checkExact · checkexact-ordering-violationerrorWhencheckExact() is placed BEFORE other validation middleware in the routeReturnsFields validated by middleware that runs after checkExact() are incorrectly flagged as unknown fields. This generates false-positive UnknownFieldsErrors that block valid requests.Required handlingAlways place checkExact() as the LAST validation middleware before the route handler. It only recognizes fields for which validation chains were registered before it runs.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[7]
- run · run-result-not-checkederrorWhen.run(req) is awaited but neither the returned ResultWithContext is checked, nor is validationResult(req) called afterward in the route handlerReturnsValidation runs and errors are stored on the request, but if the caller never checks them, all validation errors are silently ignored. The handler proceeds with potentially invalid data.Required handlingAfter await chain.run(req), EITHER check the returned result directly (result.isEmpty(), result.array()) OR call validationResult(req) in the handler. The most common pattern: await chain.run(req); const errors = validationResult(req); if (\!errors.isEmpty()) { return res.status(400).json(...); }costmediumin prodsilent failureusers seelost datavisibilitysilentSources[5]
- run · run-not-awaitederrorWhen.run(req) is called without await (fire-and-forget)ReturnsValidation starts asynchronously but completes after the route handler has already continued. Errors are never persisted to req. validationResult(req) returns empty. All fields silently pass validation.Required handlingAlways await chain.run(req). Fire-and-forget causes silent validation skips that are extremely difficult to debug — validationResult appears to pass even when fields are invalid.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[5]
- matchedData · matcheddata-used-without-validationresult-checkerrorWhenmatchedData(req) is called but the caller did NOT first call validationResult(req) and check isEmpty() — invalid fields silently absent from the returned objectReturnsReturns an object that silently omits all fields that failed validation. If the caller assumes all submitted fields are present (e.g., spreading into a DB write), invalid user input is treated as missing rather than invalid — no error is thrown.Required handlingAlways call validationResult(req) and verify isEmpty() before calling matchedData(req). Without this check, the returned object silently excludes invalid fields. Code that does `db.update({ ...matchedData(req) })` without first verifying validation passed will silently persist partial data or update with undefined fields.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[8]
- matchedData · matcheddata-optional-fields-silently-absentwarningWhenmatchedData(req) is called without { includeOptionals: true } but the code assumes all validated optional fields are present in the returned objectReturnsOptional fields that were not included in the request are absent from the result by default. Code that destructures matchedData() and assigns directly to a record update will silently skip optional fields, leaving stale values unchanged instead of clearing them (e.g., a user attempting to unset an optional profile field).Required handlingPass { includeOptionals: true } when you need optional fields present (even as undefined) in the returned object. Otherwise, distinguish between "user didn't submit this field" (absent) and "user submitted this field as empty" using req.body directly for optional fields. Failure to handle this causes silent PATCH semantics even when a PUT was intended.costlowin prodsilent failureusers seelost datavisibilitysilentSources[8]
- ExpressValidator · express-validator-custom-sanitizer-no-returnerrorWhenA custom sanitizer registered with new ExpressValidator() does not return a value (or implicitly returns undefined)ReturnsThe field's value is silently set to undefined. Validation technically "succeeds" — no error is added — but the field value is permanently corrupted to undefined in the request context. Any subsequent matchedData() call will include the field as undefined. DB writes using the field will store null/undefined.Required handlingCustom sanitizers MUST return a value. The official docs warn: "If you don't return from a custom sanitizer, your field will become undefined!" This is a silent data corruption — no exception is thrown, validation passes, but the field is destroyed. Always explicitly return the sanitized value.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[9]
- ExpressValidator · express-validator-async-validator-swallows-infra-errorwarningWhenA custom async validator performs a database or network call that rejects due to an infrastructure error (DB timeout, network failure), but the calling code does not distinguish validation failures from infrastructure failuresReturnsThe field is marked as invalid (same as a real validation failure). No exception propagates — the promise rejection is caught internally and converted to a validation error. validationResult(req) reports the field as invalid. The underlying DB/network error is silently consumed with no alerting, logging, or 500 response.Required handlingCustom async validators that make DB or network calls should catch and re-throw infrastructure errors separately. Pattern: if the error is a DB/network error (not a business rule failure), rethrow so that the route can return 500 instead of 422. Without this, a DB timeout silently looks like "invalid email" to the user.costmediumin proddegraded serviceusers seedegraded performancevisibilityvisibleSources[9]
- result-throw · result-throw-no-trycatcherrorWhenvalidationResult(req).throw() is called in a route handler not wrapped in try-catch and not using express-async-errors or Express 5ReturnsIf validation errors exist, throws an unhandled exception. Express 4's default error handler returns a 500 Internal Server Error rather than a 400 Bad Request. This leaks validation state as a server error and may expose internal error details to clients.Required handlingEither: (a) wrap in try-catch and send a structured 400 response, or (b) use express-async-errors (patches Express to handle async throws), or (c) use Express 5 which handles async route errors natively. In Express 4 without async-errors, throw() produces a 500, not a 400, and may expose error details.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10]
- result-throw · result-throw-successinfoWhenNo validation errors exist when .throw() is calledReturnsReturns void without throwing. Execution continues normally.Required handlingNo action required.costlowin proddegraded serviceusers seedegraded performancevisibilitysilentSources[10]
Sources
Every postcondition cites at least one of these. Numbered to match the footnotes above.
- [1]express-validator.github.io/docs/guideshttps://express-validator.github.io/docs/guides/getting-started
- [2]express-validator.github.io/docs/apihttps://express-validator.github.io/docs/api/validation-result
- [3]express-validator.github.io/docs/apihttps://express-validator.github.io/docs/api/validation-chain-builders
- [4]express-validator.github.io/docs/apihttps://express-validator.github.io/docs/api/check-schema
- [5]express-validator.github.io/docs/guideshttps://express-validator.github.io/docs/guides/manually-running
- [6]express-validator.github.io/docs/apihttps://express-validator.github.io/docs/api/one-of
- [7]express-validator.github.io/docs/apihttps://express-validator.github.io/docs/api/check-exact
- [8]express-validator.github.io/docs/apihttps://express-validator.github.io/docs/api/matched-data
- [9]express-validator.github.io/docs/guideshttps://express-validator.github.io/docs/guides/customizing
- [10]express-validator.github.io/docs/apihttps://express-validator.github.io/docs/api/validation-result#throw
Need a different package?
Request a profile