laravel/framework · error · RuntimeException

You must specify an orderBy clause when using this function.

Error message

You must specify an orderBy clause when using this function.

What it means

enforceOrderBy() is called by methods whose result is only meaningful with a deterministic row order — forPage(), skip()/take() with an offset, and a few cursor-style helpers. If neither $this->orders nor $this->unionOrders is populated, it throws RuntimeException, because paginating an unordered query returns arbitrary (and unstable) rows.

Solutions

  1. Add ->orderBy('id') (or another deterministic column) before paginate()/forPage()/skip().
  2. Order by a unique, monotonic column to make pagination stable across pages.
  3. If you truly want unordered rows, fetch without skip/take.

Example fix

// before
User::forPage($page, $size)->get();

// after
User::orderBy('id')->forPage($page, $size)->get();
Defensive patterns

Strategy: validation

Validate before calling

if (empty($query->orders) && empty($query->unionOrders)) {
    $query->orderBy('id');
}
$query->forPage($page, $size);

Prevention

When it happens

Trigger: ->forPage(2, 15) or ->skip(10)->take(5) on a query that has no prior orderBy() call.

Common situations: Adding pagination to an existing query and forgetting the order; relying on default insertion order which DBs do not guarantee; paginating a query that previously used an index but now does a full scan.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/e6570e8c8b1e3935. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Database/Query/Builder.php:3811

            yield from $this->connection->cursor(
                $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing
            );
        }))->map(function ($item) {
            return $this->applyAfterQueryCallbacks(new Collection([$item]))->first();
        })->reject(fn ($item) => is_null($item));
    }

    /**
     * Throw an exception if the query doesn't have an orderBy clause.
     *
     * @return void
     *
     * @throws \RuntimeException
     */
    protected function enforceOrderBy()
    {
        if (empty($this->orders) && empty($this->unionOrders)) {
            throw new RuntimeException('You must specify an orderBy clause when using this function.');
        }
    }

    /**
     * Get a collection instance containing the values of a given column.
     *
     * @param  \Illuminate\Contracts\Database\Query\Expression|string  $column
     * @param  string|null  $key
     * @return \Illuminate\Support\Collection<array-key, mixed>
     */
    public function pluck($column, $key = null)
    {
        $original = $this->columns;

        // First, we will need to select the results of the query accounting for the
        // given columns / key. Once we have the results, we will be able to take
        // the results and get the exact data that was requested for the query.
        $this->columns ??= is_null($key) || $key === $column

View on GitHub (pinned to e0f6eb3518)