mongodb/laravel-mongodb · error · LogicException

Constraints on the embedded relation

Error message

Constraints on the embedded relation "%s" are not supported.

What it means

When using withAggregate/withCount/withSum etc. on an embedded relation (EmbedsOneOrMany), MongoDB Laravel cannot apply query constraints (where, limit, offset, distinct) to the embedded documents, because aggregates on embedded data are computed in PHP from the parent document, not by a server query. The library throws this LogicException as soon as any constraint closure passed to withAggregate adds one of those clauses.

Solutions

  1. Remove the where/limit/offset/distinct constraints from the closure for the embedded relation.
  2. Filter or limit the embedded documents after fetching, e.g. compute the aggregate manually from $model->relation and filter in PHP with collections.
  3. If filtering is essential, restructure so the data is stored in a separate collection with a HasOneOrMany/BelongsToMany relation, which supports constraints.

Example fix

// before
Order::withAggregate('lines:sum(total)', fn ($q) => $q->where('refunded', false))->get();
// after
Order::withAggregate('lines:sum(total)')->get()->each(function ($order) {
    $order->lines_sum_total = collect($order->lines)->where('refunded', false)->sum('total');
});
Defensive patterns

Strategy: validation

Validate before calling

// Check the closure adds no constraints before calling withAggregate on an embedded relation
$q = $model->related()->getRelated()->newQuery();
$closure($q);
$base = $q->getQuery();
if ($base->wheres || $base->limit !== null || $base->offset !== null || $base->distinct) {
    throw new LogicException('Constraints are not supported on embedded relation aggregates.');
}

Type guard

function supportsEmbeddedConstraints($relation): bool {
    return !($relation instanceof \MongoDB\Laravel\Relations\EmbedsOneOrMany);
}

Try / catch

try {
    $result = Order::withAggregate('lines:sum(total)', fn ($q) => $q->where('active', true))->get();
} catch (\LogicException $e) {
    // fall back to computing the aggregate in PHP
    $result = Order::withAggregate('lines:sum(total)')->get();
}

Prevention

When it happens

Trigger: Calling e.g. Model::withAggregate('embeddedItems:sum(price)', fn($q) => $q->where('active', true)) or withCount('embeds', fn($q) => $q->limit(5)) where the relation is an embedsMany/embedsOne and the closure applies where/limit/offset/distinct.

Common situations: Developers migrating from SQL-backed Eloquent where filtering sub-aggregates via closures works; they reuse the same constraint closures for embedded relations and hit the limitation since MongoDB embedded aggregates are computed client-side after reading the parent document.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15). Data as JSON: /api/errors/7238cc3ded0f870c. Report an issue: GitHub.

Appendix: source

Thrown at src/Helpers/QueriesRelationshipAggregates.php:139

            '',
            sprintf('%s %s %s', $name, $function, strtolower($column)),
        ));

        return [$name, $alias];
    }

    private function assertEmbeddedConstraintsSupported(Relation $relation, string $name, Closure $constraints): void
    {
        if (! $relation instanceof EmbedsOneOrMany) {
            return;
        }

        $subQuery = $relation->getRelated()->newQuery();
        $constraints($subQuery);
        $query = $subQuery->getQuery();

        if ($query->wheres || $query->limit !== null || $query->offset !== null || $query->distinct) {
            throw new LogicException(sprintf(
                'Constraints on the embedded relation "%s" are not supported.',
                $name,
            ));
        }
    }

    /** @inheritdoc */
    public function eagerLoadRelations(array $models)
    {
        foreach ($this->withAggregates as $alias => $aggregate) {
            $this->assertAggregateNotUsedInQuery($alias);
            $this->hydrateAggregate($models, $alias, $aggregate);
        }

        return parent::eagerLoadRelations($models);
    }

    /**

View on GitHub (pinned to 0634653039)