laravel/framework · error · InvalidArgumentException

Collection given to whereMorphedTo method may not be empty.

Error message

Collection given to whereMorphedTo method may not be empty.

What it means

whereMorphedTo() builds a WHERE morph_type = X AND morph_id IN (...) clause from the supplied models. An empty collection produces no group-by bucket and cannot express a meaningful condition, so the framework rejects it with InvalidArgumentException rather than generating a no-op (always-false) query.

Source

Thrown at src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php:644

        if (is_null($model)) {
            return $this->whereNull($relation->qualifyColumn($relation->getMorphType()), $boolean);
        }

        if (is_string($model)) {
            $morphMap = Relation::morphMap();

            if (! empty($morphMap) && in_array($model, $morphMap)) {
                $model = array_search($model, $morphMap, true);
            }

            return $this->where($relation->qualifyColumn($relation->getMorphType()), $model, null, $boolean);
        }

        $models = BaseCollection::wrap($model);

        if ($models->isEmpty()) {
            throw new InvalidArgumentException('Collection given to whereMorphedTo method may not be empty.');
        }

        return $this->where(function ($query) use ($relation, $models) {
            $models->groupBy(fn ($model) => $model->getMorphClass())->each(function ($models) use ($query, $relation) {
                $query->orWhere(function ($query) use ($relation, $models) {
                    $query->where($relation->qualifyColumn($relation->getMorphType()), $models->first()->getMorphClass())
                        ->whereIn($relation->qualifyColumn($relation->getForeignKeyName()), $models->map->getKey());
                });
            });
        }, null, null, $boolean);
    }

    /**
     * Add a not morph-to relationship condition to the query.
     *
     * @param  \Illuminate\Database\Eloquent\Relations\MorphTo<*, *>|string  $relation
     * @param  \Illuminate\Database\Eloquent\Model|iterable<int, \Illuminate\Database\Eloquent\Model>|string  $model
     * @return $this

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Guard for emptiness before calling: if ($models->isNotEmpty()) { $query->whereMorphedTo(...); }.
  2. When the intent is 'match nothing', use whereRaw('1=0') or skip applying the filter explicitly.
  3. Pass null (matches NULL morph_type) or a single model instead of an empty collection where semantics allow.

Example fix

// before
$query->whereMorphedTo('commentable', $selectedModels); // could be empty

// after
if ($selectedModels->isNotEmpty()) {
    $query->whereMorphedTo('commentable', $selectedModels);
}
Defensive patterns

Strategy: validation

Validate before calling

$models = \Illuminate\Support\Collection::wrap($model);
if ($models->isEmpty()) {
    // decide: skip filter, or throw a domain-level exception
    return $query;
}
return $query->whereMorphedTo($relation, $models);

Type guard

function hasMorphModels(mixed $model): bool
{
    return ! \Illuminate\Support\Collection::wrap($model)->isEmpty();
}

Try / catch

try {
    return $query->whereMorphedTo($relation, $models);
} catch (\InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'may not be empty')) {
        return $query; // no filter applied
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling $query->whereMorphedTo('commentable', collect([])) (or []), typically because an upstream filter that was supposed to supply models returned nothing.

Common situations: Dynamic filters where the user selected zero items; collections built from optional request inputs that resolved to empty; looping over grouped data where a group is legitimately empty.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/278aec7758b65da3.json. Report an issue: GitHub.