mongodb/laravel-mongodb · error · BadMethodCallException
Aggregation builder does not support previous query-builder…
Error message
Aggregation builder does not support previous query-builder instructions. Use a $match stage instead.
What it means
The fluent AggregationBuilder starts from a clean pipeline; existing query-builder where clauses cannot be converted automatically. If ->where() etc. were applied before calling ->aggregate() with no function, this BadMethodCallException is thrown, directing you to use a $match stage.
Solutions
- Move each ->where(...) condition into a ->match(...) stage on the AggregationBuilder.
- Call aggregate(null) on a fresh, unfiltered Builder instance.
- If you want where-clauses translated for you, use aggregateRaw()/group aggregations instead of the fluent builder.
Example fix
// before
Model::where('status', 'active')->aggregate(null);
// after
Model::aggregate(null)->match('status', 'active'); Defensive patterns
Strategy: validation
Validate before calling
if (! empty($query->getQuery()->wheres)) {
// convert wheres to a $match stage before the fluent builder call
}
$agg = $fresh = Model::query()->aggregate(null); Type guard
function hasQueryBuilderState(Illuminate\Database\Eloquent\Builder $q): bool { return ! empty($q->getQuery()->wheres); } Try / catch
try {
$agg = $query->aggregate(null);
} catch (BadMethodCallException $e) {
if (str_contains($e->getMessage(), '$match stage')) {
$agg = $query->getModel()->query()->aggregate(null)->match('status', 'active');
} else { throw $e; }
} Prevention
- Start fluent aggregation from a fresh Model::query(), not a filtered builder
- Express filters via ->match(...) stages on the AggregationBuilder
- Audit helpers that accept a Builder and call aggregate(null)
- Write tests covering mixed where()+aggregate(null) usage
When it happens
Trigger: Chaining like Model::where('status','active')->aggregate(null) — wheres are non-empty when the fluent builder path runs.
Common situations: Developers reusing an existing filtered query object and switching to the aggregation builder, expecting filters to be preserved.
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
- Columns cannot be specified to create an aggregation…
- The stage name " " is invalid. It must start with a "$"…
- Query not compatible with cursor
- Aggregation builder requires package mongodb/builder 0.2+
- Aggregating by group requires zero or one columns.
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/4daf729ed3fb6416.
Report an issue: GitHub.
Appendix: source
Thrown at src/Query/Builder.php:586
/** @return ($function is null ? AggregationBuilder : mixed) */
#[Override]
public function aggregate($function = null, $columns = ['*'])
{
assert(is_array($columns), new TypeError(sprintf('Argument #2 ($columns) must be of type array, %s given', get_debug_type($columns))));
if ($function === null) {
if (! trait_exists(FluentFactoryTrait::class)) {
// This error will be unreachable when the mongodb/builder package will be merged into mongodb/mongodb
throw new BadMethodCallException('Aggregation builder requires package mongodb/builder 0.2+');
}
if ($columns !== ['*']) {
throw new InvalidArgumentException('Columns cannot be specified to create an aggregation builder. Add a $project stage instead.');
}
if ($this->wheres) {
throw new BadMethodCallException('Aggregation builder does not support previous query-builder instructions. Use a $match stage instead.');
}
return new AggregationBuilder($this->collection, $this->options);
}
$this->aggregate = [
'function' => $function,
'columns' => $columns,
];
$previousColumns = $this->columns;
// We will also back up the select bindings since the select clause will be
// removed when performing the aggregate function. Once the query is run
// we will add the bindings back onto this query so they can get used.
$previousSelectBindings = $this->bindings['select'];
$this->bindings['select'] = [];View on GitHub (pinned to 0634653039)