Skip to main content
next-safe-env follows one rule for validation failures: fail at startup, never at runtime. When createEnv() is called at module load time, every field in the schema is validated before the function returns. If any field fails, all failures are collected first - the engine never short-circuits on the first error - and the process exits with a non-zero code after printing a complete list of every problem at once.

What the error output looks like

When validation fails, you see a structured message that lists every bad field along with what was expected, what was actually received, and a summary of how many server and client vars passed or failed:
Every failure line includes:
  • Field name - the exact key from your schema, left-padded for alignment
  • What was expected - the constraint that was not satisfied (e.g. valid URL, length >= 32, <= 65535)
  • What was received - the raw string value that was present, or "undefined" if the variable was missing
The summary block counts server and client vars independently, so you can see at a glance whether the failures are concentrated in one layer.

The EnvValidationError class

When validation fails, next-safe-env creates an instance of EnvValidationError and either passes it to your onValidationError handler or, if none is provided, calls console.error(err.format()) and process.exit(1) by default.

failures: ValidationFailure[]

An array containing one entry per failed field. Each entry has the shape:

stats: ValidationStats

An object with counts broken down by server and client:

format(): string

Returns the full pretty-printed multi-line string shown in the output above. This is what the default handler passes to console.error. Call it when you want to log the human-readable version.

toJSON(): unknown

Returns a plain JSON-serializable object:
Use toJSON() when you need to send the error to a structured logging system, a remote error tracker, or any destination that expects JSON rather than a formatted string.

Custom error handlers with onValidationError

You can replace the default console.error + process.exit(1) behavior by providing an onValidationError function in the config:
The handler receives the EnvValidationError instance. You have access to err.failures, err.stats, err.format(), and err.toJSON() - use whichever form suits your logging infrastructure.
onValidationError must never return. The engine does not call process.exit() after invoking your handler. If the handler returns normally, execution continues with an invalid env object - every field that failed validation will be undefined or the wrong type, and your application will behave unpredictably. Always call process.exit() or throw an error inside the handler.
A handler for a structured logging setup might look like this:
This sends the structured failures array and stats object to your log aggregator while preserving the non-zero exit code that signals a failed deployment to your process manager or container orchestrator.
The onValidationError option accepts a function typed as (error: ValidationErrorShape) => never. The never return type is enforced by TypeScript - if your handler has a code path that could return, the compiler will error.