logo
podcast Podcast
get help Get Unstuck

Why use firstOrFail when we already validated the record exists?

There is a good reason

Joel Clermont
Joel Clermont
2025-07-08

Take a look at this code example:

// relevant rules from the form request
'emails.*' => [
    'bail',
    'required',
    'email',
    'distinct',
    Rule::exists('users', 'email')->whereNot('id', $this->user()->id),
]

// code in the controller action
$validated = $request->validated();
foreach ($validated['emails'] as $email) {
    $user = User::where('email', $email)->firstOrFail();
    // do something with each $user
}

Does anything look redundant to you?

Notice how the validation rule requires the email to exist in the users table. So why then also use firstOrFail() in the controller? We know the user must exist if it got past the request validation.

In this case, it's not that we expect it to throw a ModelNotFoundException. We know that can never happen.

But by using firstOrFail(), we are now narrowing the type of $user from ?User to User.

This means that further uses of $user inside this loop don't have to handle the possibility of it being null.

It simplifies our code and satisfies static analysis tooling.

And as a bonus, we get the added protection of the additional check, just in case validation rules change in the future.

Here to help,

Joel

P.S. How do you know how far to go with static analysis in your project? We can help strike the balance between safety and not introducing too much friction.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice you can use.