{"record":{"id":"86eb2c8d00baed3a","repo":"mongodb/laravel-mongodb","slug":"columns-cannot-be-specified-to-create-an-aggregation-builder","errorCode":null,"errorMessage":"Columns cannot be specified to create an aggregation builder. Add a $project stage instead.","messagePattern":"Columns cannot be specified to create an aggregation builder\\. Add a \\$project stage instead\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Query/Builder.php","lineNumber":582,"sourceCode":"        ];\n\n        return md5(serialize(array_values($key)));\n    }\n\n    /** @return ($function is null ? AggregationBuilder : mixed) */\n    #[Override]\n    public function aggregate($function = null, $columns = ['*'])\n    {\n        assert(is_array($columns), new TypeError(sprintf('Argument #2 ($columns) must be of type array, %s given', get_debug_type($columns))));\n\n        if ($function === null) {\n            if (! trait_exists(FluentFactoryTrait::class)) {\n                // This error will be unreachable when the mongodb/builder package will be merged into mongodb/mongodb\n                throw new BadMethodCallException('Aggregation builder requires package mongodb/builder 0.2+');\n            }\n\n            if ($columns !== ['*']) {\n                throw new InvalidArgumentException('Columns cannot be specified to create an aggregation builder. Add a $project stage instead.');\n            }\n\n            if ($this->wheres) {\n                throw new BadMethodCallException('Aggregation builder does not support previous query-builder instructions. Use a $match stage instead.');\n            }\n\n            return new AggregationBuilder($this->collection, $this->options);\n        }\n\n        $this->aggregate = [\n            'function' => $function,\n            'columns' => $columns,\n        ];\n\n        $previousColumns = $this->columns;\n\n        // We will also back up the select bindings since the select clause will be\n        // removed when performing the aggregate function. Once the query is run","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/mongodb/laravel-mongodb/blob/0634653039468ceb0268a69192bdac64469ed043/src/Query/Builder.php#L564-L600","documentation":"When creating a fluent AggregationBuilder via ->aggregate() with no function, column selection is meaningless because projections must be expressed as a $project stage. Passing any columns other than ['*'] raises this InvalidArgumentException.","triggerScenarios":"Calling ->aggregate('avg', ['price']) — no wait, the builder path only triggers with $function === null; specifically ->aggregate(null, ['price']) or ->aggregate(null, 'price') cast to array.","commonSituations":"Developers mixing the fluent-builder call style (no function) with the aggregate-with-columns style, expecting column selection to carry over.","solutions":["Call ->aggregate(null) (columns default to ['*']) and add a ->project(...) stage on the AggregationBuilder instead.","If you want aggregation over specific columns, pass a function: ->aggregate('avg', ['price'])."],"exampleFix":"// before\n$agg = Model::aggregate(null, ['price']);\n// after\n$agg = Model::aggregate(null)->project('price');","handlingStrategy":"validation","validationCode":"if ($function === null && $columns !== ['*']) {\n    $columns = ['*']; // or move columns into a $project stage\n}\n$agg = $model->aggregate($function, $columns);","typeGuard":null,"tryCatchPattern":"try {\n    $agg = Model::aggregate(null, $columns);\n} catch (InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'Columns cannot be specified')) {\n        $agg = Model::aggregate(null)->project($columns);\n    } else { throw $e; }\n}","preventionTips":["Call aggregate(null) without columns and use ->project() on the builder","Only pass columns when a function like 'avg' is supplied","Add static analysis/tests asserting builder-style calls use ['*']","Document the difference between aggregate(fn, cols) and the fluent builder in your codebase"],"tags":["aggregation","columns","builder"],"backgroundTag":"invalid-argument-value","analyzedSha":"0634653039468ceb0268a69192bdac64469ed043","analyzedAt":"2026-09-15T02:56:37.067Z","contentChangedAt":"2026-09-15T02:56:37.067Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}