Common Validation Mistakes in Express (and How to Fix Them)
Validation has predictable failure modes. Here are common mistakes and fixes.
Common Validation Mistakes in Express
Validation is easy to get wrong. Here are common mistakes and how to fix them.
Mistake 1: No Validation at All
You trust the request body. Missing fields crash the server. Fix: validate at the boundary with Zod or express-validator.
Mistake 2: Validating Only the Body
You validate req.body but forget req.params and req.query. An invalid ObjectId crashes Mongoose. Fix: validate all three. Write validate, validateParams, validateQuery factories.
Mistake 3: Not Replacing req.body With Parsed Data
You validate but use the original req.body downstream. Coercion (e.g., string to number) is lost. Fix: replace req.body with result.data after safeParse.
Mistake 4: No Type Coercion
Query params are always strings. You parseInt manually and forget sometimes. Fix: use Zod's coerce (z.coerce.number()) to handle this consistently.
Mistake 5: Validation in Controllers
You validate inside each controller. Duplicated logic. Fix: validate in a middleware. Apply per route.
Mistake 6: Validation Too Late
You validate after some work is done. Partial state changes. Fix: validate first, before any work. The handler should only run with valid input.
Mistake 7: Generic Error Messages
You return 'Invalid input' without details. Clients cannot fix the issue. Fix: return field-level errors. Zod's result.error.issues has path, message, and code for each error.
Mistake 8: Not Handling Mongoose Validation Errors
You let Mongoose's ValidationError bubble up as a 500. Fix: catch it in the error handler. If err.name === 'ValidationError', return 400 with field list.
Mistake 9: Not Using runValidators on Updates
You use findByIdAndUpdate without runValidators. Validation does not run. Fix: always pass { runValidators: true, new: true }.
Mistake 10: Trusting Client-Side Validation
You validate only on the client. A user can bypass it with curl. Fix: always validate on the server. Client validation is for UX, not security.
The Takeaway
Common validation mistakes: no validation, only validating body, not replacing req.body with parsed data, no type coercion, validating in controllers, validating too late, generic error messages, not handling Mongoose ValidationErrors, no runValidators on updates, and trusting client-side validation. Fix them on day one.
No validation at all, only validating the body (forgetting params and query), not replacing req.body with parsed data, no type coercion, validating in controllers (duplication), validating too late, generic error messages, not handling Mongoose ValidationErrors, no runValidators on updates, and trusting client-side validation.
Invalid params (e.g., a non-24-char ObjectId) crash Mongoose. Invalid query (e.g., a non-numeric skip) breaks pagination. Validate all three with separate factories: validate, validateParams, validateQuery.
Because Zod coerces types (string to number, defaults, transforms). If you keep the original req.body, downstream code uses uncoerced strings. Replace req.body = result.data so the handler sees the parsed, coerced data.
It duplicates logic across controllers. Validation in a middleware is applied per route and reusable. Controllers should focus on business logic, not validation.
A user can bypass it with curl, Postman, or a custom client. Client validation improves UX (instant feedback); server validation is for security. Always validate on the server, no matter what the client does.
Ready to master Node.js completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master Node.js
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

