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() when the supplied EloquentCollection (or collection built from a single model) is empty. Like whereBelongsTo, this method needs at least one related model to resolve the belongsToMany relationship name and to build the matching sub-query. An empty input is treated as a programmer error rather than an empty filter.

Solutions

  1. Check the collection is non-empty before calling whereAttachedTo.
  2. Branch to a no-match query (e.g. whereRaw('1=0')) when the collection is empty.
  3. Pass a single Model instance when only one related item is involved.

Example fix

// before
$tags = Tag::whereIn('slug', $request->input('tags', []))->get();
$query = Post::whereAttachedTo($tags);

// after
$tags = Tag::whereIn('slug', $request->input('tags', []))->get();
$query = $tags->isEmpty() ? Post::whereRaw('1=0') : Post::whereAttachedTo($tags);
Defensive patterns

Strategy: validation

Validate before calling

if ($related instanceof \Illuminate\Database\Eloquent\Collection && $related->isEmpty()) {
    return Post::whereRaw('1 = 0'); // no rows match an empty attachment set
}

Type guard

function hasAttachedItems(\Illuminate\Database\Eloquent\Collection $c): bool {
    return $c->isNotEmpty();
}

Try / catch

try {
    $query = Post::whereAttachedTo($tags);
} catch (\InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'may not be empty')) {
        $query = Post::whereRaw('1 = 0');
    } else { throw $e; }
}

Prevention

When it happens

Trigger: Calling Post::whereAttachedTo($emptyTagCollection) or ->whereAttachedTo(Tag::where('name', 'nonexistent')->get()) where the collection has no models. The method always builds a collection first, then checks isEmpty().

Common situations: Filtering tags/categories to none before passing them in; passing a collection from an optional relation that resolved to nothing; UI where a user selects zero items then submits.

Related errors


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

Appendix: 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 e0f6eb3518)