laravel/framework · error · RecordNotFoundException
No record found for the given query.
Error message
No record found for the given query.
What it means
RecordNotFoundException from firstOrFail() when the query returns no rows. firstOrFail is the strict variant of first(): it returns the single result or throws, used to enforce that an expected record exists (often inside controllers before responding 404).
Solutions
- Confirm the lookup value is correct and the row exists in the DB.
- Provide a custom message: firstOrFail(['*'], 'Post not found') for clearer errors.
- If absence is legitimate, use first() and handle null instead of firstOrFail().
- Use route-model-binding with explicit key: Route::get('posts/{post:slug}') to fail at the routing layer with 404.
Example fix
// before
$post = Post::where('slug', $slug)->firstOrFail();
// after - clearer message
$post = Post::where('slug', $slug)->firstOrFail(['*'], "Post [$slug] not found");
// or accept absence
$post = Post::where('slug', $slug)->first();
abort_unless($post, 404); Defensive patterns
Strategy: try-catch
Validate before calling
// Optional pre-check using exists() to give a clearer error or branch.
if (! Model::where('slug', $slug)->exists()) {
abort(404, "Resource [$slug] not found");
}
$model = Model::where('slug', $slug)->firstOrFail(['*'], "Resource [$slug] not found"); Type guard
function recordExists(\Illuminate\Database\Eloquent\Builder $q): bool
{
return $q->exists();
} Try / catch
use Illuminate\Database\RecordNotFoundException;
try {
$model = Model::where('slug', $slug)->firstOrFail(['*'], 'Post not found');
} catch (RecordNotFoundException $e) {
abort(404, $e->getMessage());
} Prevention
- Use route-model-binding with implicit key constraints so missing records 404 at the routing layer.
- Pass a descriptive custom message to firstOrFail().
- If absence is a valid state, use first() and handle null instead of firstOrFail().
When it happens
Trigger: Model::where('slug', $slug)->firstOrFail() when no row matches; firstOrFail on a filtered query in a show() action with a missing/typo'd id; chain after whereHas that yields nothing.
Common situations: User requests a resource that was deleted; wrong route-model-binding key; filter conditions too restrictive; race where a record is removed between check and fetch.
Related errors
- $count records were found.
- A subquery must be a query builder instance, a Closure, or…
- Collection given to whereAttachedTo method may not be empty.
- Collection given to whereBelongsTo method may not be empty.
- Collection given to whereMorphedTo method may not be empty.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/a75ee82dea16839e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Concerns/BuildsQueries.php:384
return $this->limit(1)->get($columns)->first();
}
/**
* Execute the query and get the first result or throw an exception.
*
* @param array|string $columns
* @param string|null $message
* @return TValue
*
* @throws \Illuminate\Database\RecordNotFoundException
*/
public function firstOrFail($columns = ['*'], $message = null)
{
if (! is_null($result = $this->first($columns))) {
return $result;
}
throw new RecordNotFoundException($message ?: 'No record found for the given query.');
}
/**
* Execute the query and get the first result if it's the sole matching record.
*
* @param array|string $columns
* @return TValue
*
* @throws \Illuminate\Database\RecordsNotFoundException
* @throws \Illuminate\Database\MultipleRecordsFoundException
*/
public function sole($columns = ['*'])
{
$result = $this->limit(2)->get($columns);
$count = $result->count();
if ($count === 0) {View on GitHub (pinned to e0f6eb3518)