mongodb/laravel-mongodb · error · InvalidArgumentException
The stage name " " is invalid. It must start with a "$"…
Error message
The stage name "%s" is invalid. It must start with a "$" sign.
What it means
AggregationBuilder::addRawStage() appends a raw pipeline stage, and MongoDB pipeline stage names must begin with '$'. This guard rejects operator strings missing the leading dollar sign before they can produce an invalid aggregation pipeline.
Solutions
- Prefix the operator with '$': addRawStage('$match', $filter).
- For full typed stage building, use the fluent aggregation builder methods (match(), group(), etc.) instead of addRawStage.
- Check the stage name against MongoDB's aggregation pipeline stage reference.
Example fix
// before
$builder->addRawStage('match', ['status' => 'active']);
// after
$builder->addRawStage('$match', ['status' => 'active']); Defensive patterns
Strategy: validation
Validate before calling
if (! str_starts_with($operator, '$')) {
throw new InvalidArgumentException('Stage must start with $');
}
$builder->addRawStage($operator, $value); Type guard
function isValidStageName(string $op): bool { return str_starts_with($op, '$'); } Try / catch
try {
$builder->addRawStage($operator, $value);
} catch (InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'must start with a "$" sign')) {
$operator = '$' . ltrim($operator, '$');
$builder->addRawStage($operator, $value);
} else { throw $e; }
} Prevention
- Always write raw stage operators with the '$' prefix ('match', 'group')
- Prefer built-in fluent stage methods over addRawStage when available
- Keep a list of valid MongoDB stage names in your linter/tests
- Add unit tests asserting stage names start with '$'
When it happens
Trigger: Calling ->addRawStage('match', [...]) or any operator string without a leading '$', e.g. 'group', 'project', 'lookup'.
Common situations: Developers coming from SQL-ish builder APIs forget the '$' prefix, or paste a stage name from documentation that lists stages without the '$'.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Query not compatible with cursor
- Aggregation builder requires package mongodb/builder 0.2+
- Columns cannot be specified to create an aggregation…
- Aggregation builder does not support previous query-builder…
- Aggregating by group requires zero or one columns.
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/537f5145e63c8e66.
Report an issue: GitHub.
Appendix: source
Thrown at src/Query/AggregationBuilder.php:38
class AggregationBuilder
{
use FluentFactoryTrait;
public function __construct(
private Collection $collection,
private readonly array $options = [],
) {
}
/**
* Add a stage without using the builder. Necessary if the stage is built
* outside the builder, or it is not yet supported by the library.
*/
public function addRawStage(string $operator, mixed $value): static
{
if (! str_starts_with($operator, '$')) {
throw new InvalidArgumentException(sprintf('The stage name "%s" is invalid. It must start with a "$" sign.', $operator));
}
$this->pipeline[] = [$operator => $value];
return $this;
}
/**
* Execute the aggregation pipeline and return the results.
*/
public function get(array $options = []): LaravelCollection|LazyCollection
{
$cursor = $this->execute($options);
return collect($cursor->toArray());
}
/**View on GitHub (pinned to 0634653039)