Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

How Laravel Handles Failed Validation Redirects

When a browser submits a Laravel form with invalid data, Laravel validates the request, sends the browser back to the previous URL, and stores the validation messages in the session for the next page request. A session is short-lived server-side storage that carries data between requests. Laravel also temporarily stores eligible submitted values so the form can show them again.

The redirect path applies to requests that do not expect JSON. Requests that expect JSON receive a JSON validation response instead. The flow below describes Laravel 13.x; check the documentation and source for your version if you use an older release. Laravel’s validation documentation describes both response modes.

How Laravel chooses the response

When Laravel’s validate method or a form request finds invalid data, it throws a ValidationException, which carries the validation errors. Laravel’s exception handler checks the request’s expected response format. For a traditional browser form, it redirects to the previous URL. When the request expects JSON, Laravel returns a JSON response with the errors. The exception handler implements this distinction.

A form request uses the previous URL as its default redirect destination. You can configure a different destination for a form request, as shown in Laravel’s form request source.

How errors and old input reach the next page

For a redirect, Laravel temporarily stores the validation messages and eligible submitted input in the session for the next request. Laravel calls this flashing: the data is available to the next request rather than kept as a permanent record. Laravel excludes input listed in the exception handler’s dontFlash configuration.

On the next request, middleware in the web group makes the errors available to views as $errors. If the session contains no validation errors, the middleware provides an empty error bag. A Blade view can display a field’s first error like this:

@error('email')
    <div>{{ $message }}</div>
@enderror

Laravel also temporarily stores eligible old input so the view can fill in the fields again. Error messages and old input are separate: naming an error bag separates messages, but does not create a separate old-input store for each form.

How named error bags separate forms

An error bag groups validation messages under a name. Views access the default bag through $errors; a named bag lets a view select messages for one form. This helps when a page has multiple forms, such as login and registration, because each form can display its own errors.

For example, a redirect can assign validation messages to a login bag:

return redirect('/register')->withErrors($validator, 'login');

The view can then display an email error from that bag:

{{ $errors->login->first('email') }}

Blade’s @error directive also accepts the bag name:

@error('email', 'login')
    <div>{{ $message }}</div>
@enderror

You can also name the bag when you validate with an existing validator by using validateWithBag, or when you configure a form request with the ErrorBag attribute. The validation documentation shows these options.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *