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

  1. Confirm the lookup value is correct and the row exists in the DB.
  2. Provide a custom message: firstOrFail(['*'], 'Post not found') for clearer errors.
  3. If absence is legitimate, use first() and handle null instead of firstOrFail().
  4. 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

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


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)