laravel/framework · error · InvalidArgumentException

Collection given to whereAttachedTo method may not be empty.

Error message

Collection given to whereAttachedTo method may not be empty.

What it means

Thrown by whereAttachedTo (the BelongsToMany analog of whereBelongsTo) when the passed EloquentCollection is empty. The method resolves the relationship name from the first element and uses its keys for a whereIn, so an empty collection cannot be processed. It is an InvalidArgumentException indicating a misuse of the API.

Source

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

    /**
     * Add a "belongs to many" relationship where clause to the query.
     *
     * @param  \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model>  $related
     * @param  string|null  $relationshipName
     * @param  string  $boolean
     * @return $this
     *
     * @throws \InvalidArgumentException
     * @throws \Illuminate\Database\Eloquent\RelationNotFoundException
     */
    public function whereAttachedTo($related, $relationshipName = null, $boolean = 'and')
    {
        $relatedCollection = $related instanceof EloquentCollection ? $related : $related->newCollection([$related]);

        $related = $relatedCollection->first();

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

        if ($relationshipName === null) {
            $relationshipName = Str::plural(Str::camel(class_basename($related)));
        }

        try {
            $relationship = $this->model->{$relationshipName}();
        } catch (BadMethodCallException) {
            throw RelationNotFoundException::make($this->model, $relationshipName);
        }

        if (! $relationship instanceof BelongsToMany) {
            throw RelationNotFoundException::make($this->model, $relationshipName, BelongsToMany::class);
        }

        $this->has(
            $relationshipName,

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Check the collection is non-empty before calling whereAttachedTo (if ($collection->isNotEmpty())).
  2. Wrap with when() to make the clause conditional on non-empty input.
  3. Fall back to a deliberately empty result set when the intent is 'match nothing'.

Example fix

// before
Post::whereAttachedTo($tags)->get();

// after
Post::when($tags->isNotEmpty(), fn ($q) => $q->whereAttachedTo($tags))->get();
Defensive patterns

Strategy: validation

Validate before calling

if ($related instanceof \Illuminate\Database\Eloquent\Collection && $related->isEmpty()) {
    return Post::whereRaw('1=0')->get();
}
Post::whereAttachedTo($related)->get();

Type guard

function hasAttachedModels($related): bool {
    return $related instanceof \Illuminate\Database\Eloquent\Model
        || ($related instanceof \Illuminate\Database\Eloquent\Collection && $related->isNotEmpty());
}

Try / catch

try {
    Post::whereAttachedTo($related)->get();
} catch (\InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'may not be empty')) {
        return collect();
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling User::whereAttachedTo($emptyCollection) where the collection represents tags/roles/etc. to filter by attachment, but the collection contains no models.

Common situations: Filtering a many-to-many relation by a list of related models that a previous query produced empty (e.g. filtering posts by tags when no tags match a prior search).

Related errors


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