mongodb/laravel-mongodb · error · InvalidArgumentException

A pipeline exceeds the maximum of

Error message

A pipeline exceeds the maximum of %d stages.

What it means

One of the aggregation pipelines in the command (top-level or a sub-pipeline inside $facet/$lookup/$unionWith) has more than 1000 stages, matching MongoDB's documented pipeline stage limit. The library rejects it up front instead of letting the server fail.

Solutions

  1. Reduce the number of stages to 1000 or fewer, merging consecutive $match stages into one with $and or $in.
  2. Combine consecutive expression stages (e.g. many $addFields into one $addFields document).
  3. Filter data before the pipeline (e.g. in application code or with a $match on indexed fields) rather than chaining hundreds of stages.

Example fix

// before: pipeline with 1500 entries, one {"$match": {"status": "s"}} per status
// after
{"aggregate": "users", "pipeline": [{"$match": {"status": {"$in": ["a", "b", "c"]}}}, {"$limit": 100}]}
Defensive patterns

Strategy: validation

Validate before calling

$countStages = fn (array $p): int => array_sum(array_map(
    fn ($s) => ((string) array_key_first($s) === '$facet' && is_array($s['$facet']))
        ? array_sum(array_map($countStages, $s['$facet']))
        : 1,
    $p
));
if (count($pipeline) > 1000) { throw new \InvalidArgumentException('pipeline has more than 1000 stages'); }

Try / catch

try {
    $result = $tool->handle($request);
} catch (\InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'maximum of 1000 stages')) {
        // merge/collapse stages and retry
    }
}

Prevention

When it happens

Trigger: An aggregate command with a `pipeline` array longer than 1000 entries, or any nested sub-pipeline (inside $facet, $lookup.pipeline, $unionWith.pipeline) exceeding 1000 stages.

Common situations: Programmatically generated pipelines that unroll thousands of $match/$addFields stages; bulk-converted query builders; AI-generated pipelines that repeat stages instead of using $in or aggregation expressions.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at src/Tools/DatabaseQuery.php:137

            $this->ensureNoNestedWriteInAggregation($command['pipeline'] ?? []);
        }

        return $connection->getDatabase()->command($command)->toArray();
    }

    /**
     * @param array<int, array<string, mixed>> $pipeline
     *
     * @throws InvalidArgumentException
     */
    private function ensureNoNestedWriteInAggregation(array $pipeline, int $level = 1): void
    {
        if ($level > self::MAX_NESTING_LEVEL) {
            throw new InvalidArgumentException(sprintf('Aggregation nesting exceeds the maximum of %d levels.', self::MAX_NESTING_LEVEL));
        }

        if (count($pipeline) > self::MAX_STAGES_PER_PIPELINE) {
            throw new InvalidArgumentException(sprintf('A pipeline exceeds the maximum of %d stages.', self::MAX_STAGES_PER_PIPELINE));
        }

        // These aggregation stages may contain nested aggregation pipelines
        // and must be checked for write ops recursively.
        $supportsNestedWrites = ['facet', 'lookup', 'unionWith'];

        // Every known read-only aggregation stage. Kept as an allow list (rather than
        // denying $merge/$out) so that write stages added in the future are rejected by
        // default. See https://www.mongodb.com/docs/manual/reference/mql/aggregation-stages
        $allowList = array_merge($supportsNestedWrites, [
            'addFields',
            'bucket',
            'bucketAuto',
            'changeStream',
            'changeStreamSplitLargeEvent',
            'collStats',
            'count',
            'currentOp',

View on GitHub (pinned to 0634653039)