mongodb/laravel-mongodb · error · RuntimeException
Query not compatible with cursor
Error message
Query not compatible with cursor
What it means
Builder::cursor() expects getFresh(..., true) to return a LazyCollection for a true streaming cursor. If the underlying query path (e.g. an aggregation result) returns something else — an array/Collection — the query is not cursor-compatible and this RuntimeException is thrown.
Solutions
- Remove ->groupBy() or aggregation transformations before calling cursor(), or iterate with ->get() instead.
- Use cursor() only on plain find-style queries.
- If memory is a concern with aggregations, use aggregateRaw with a cursor via the collection directly, or paginate.
Example fix
// before
User::groupBy('type')->cursor();
// after
User::cursor(); // or User::groupBy('type')->get() Defensive patterns
Strategy: type-guard
Validate before calling
if ($query->getQuery()->groups) {
// cannot cursor(); use get() or remove groupBy
}
$result = $query->cursor(); Type guard
function canUseCursor(Illuminate\Database\Eloquent\Builder $q): bool { return empty($q->getQuery()->groups); } Try / catch
try {
foreach ($query->cursor() as $doc) { /* ... */ }
} catch (RuntimeException $e) {
if ($e->getMessage() === 'Query not compatible with cursor') {
foreach ($query->get() as $doc) { /* fallback */ }
} else { throw $e; }
} Prevention
- Never chain cursor() after groupBy()/aggregate()
- Use cursor() only on straightforward find-style queries
- Wrap streaming iteration in try/catch with a get() fallback when unsure
- Test memory-sensitive code paths with representative data
When it happens
Trigger: Calling ->cursor() on a query whose result is not a LazyCollection, such as after ->groupBy() (which forces an aggregation pipeline executed via aggregate() returning a plain result) or other transformed queries.
Common situations: Developers chaining cursor() onto aggregate/groupBy queries to reduce memory, unaware that grouped results cannot stream; Laravel Eloquent Builder uses the same pattern with getQuery()->cursor().
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
- The stage name " " is invalid. It must start with a "$"…
- 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/4efae2da433ad8bf.
Report an issue: GitHub.
Appendix: source
Thrown at src/Query/Builder.php:259
}
/** @inheritdoc */
#[Override]
public function get($columns = [])
{
return $this->getFresh($columns);
}
/** @inheritdoc */
#[Override]
public function cursor($columns = [])
{
$result = $this->getFresh($columns, true);
if ($result instanceof LazyCollection) {
return $result;
}
throw new RuntimeException('Query not compatible with cursor');
}
/**
* Die and dump the current MongoDB query
*
* @return never-return
*/
#[Override]
public function dd()
{
dd($this->toMql());
}
/**
* Dump the current MongoDB query
*
* @param mixed ...$args
*View on GitHub (pinned to 0634653039)