laravel/framework · error · LogicException

Unable to create query for collection with mixed types.

Error message

Unable to create query for collection with mixed types.

What it means

toQuery() needs a single concrete class to build the query. If the collection contains models of different classes (determined via instanceof of the first model's class), it raises a LogicException because no single table can satisfy the keys.

Source

Thrown at src/Illuminate/Database/Eloquent/Collection.php:941

    /**
     * Get the Eloquent query builder from the collection.
     *
     * @return \Illuminate\Database\Eloquent\Builder<TModel>
     *
     * @throws \LogicException
     */
    public function toQuery()
    {
        $model = $this->first();

        if (! $model) {
            throw new LogicException('Unable to create query for empty collection.');
        }

        $class = get_class($model);

        if ($this->contains(fn ($model) => ! $model instanceof $class)) {
            throw new LogicException('Unable to create query for collection with mixed types.');
        }

        return $model->newModelQuery()->whereKey($this->modelKeys());
    }
}

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Group by class and call toQuery() per group.
  2. Operate on a single class only: filter the collection to one type first.
  3. If a shared base class/table exists, re-query via that model's query builder with whereKey() on the IDs.

Example fix

// before
$models = collect([$post, $comment]);
$models->toQuery(); // mixed types -> throws

// after
$models->groupBy(fn ($m) => get_class($m))
    ->each(fn ($group) => $group->toQuery()->delete());
Defensive patterns

Strategy: validation

Validate before calling

$types = $collection->map(fn ($m) => get_class($m))->unique();
if ($types->count() > 1) {
    throw new \LogicException('Mixed types: ' . $types->implode(','));
}
return $collection->toQuery();

Type guard

function isHomogeneousModels(\Illuminate\Database\Eloquent\Collection $c): bool
{
    if ($c->isEmpty()) return false;
    $cls = get_class($c->first());
    return $c->every(fn ($m) => $m instanceof $cls);
}

Try / catch

try {
    return $collection->toQuery();
} catch (\LogicException $e) {
    if (str_contains($e->getMessage(), 'mixed types')) {
        // handle per-type
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling ->toQuery() on a collection holding mixed types, e.g. collect([new Post, new Comment])->toQuery(), or a polymorphic relation result that contains multiple concrete classes without a shared queryable table.

Common situations: Building a collection from a union of queries of different models; polymorphic 'morphMany' results that include more than one related class; manually merging model instances into one collection.

Related errors


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