mongodb/node-mongodb-native · error · MongoAPIError
Cannot use $out or $merge stage with ITERATION timeoutMode
Error message
Cannot use $out or $merge stage with ITERATION timeoutMode
What it means
Thrown by the AggregationCursor constructor (MongoAPIError) when timeoutMS is set, timeoutMode is ITERATION, and the final pipeline stage is $merge or $out. ITERATION mode resets the timeout per getMore batch, but $out/$merge write the entire result set in one shot on the first batch, so a per-iteration timeout cannot meaningfully bound them. The driver rejects the combination at construction time.
Source
Thrown at src/cursor/aggregation_cursor.ts:57
constructor(
client: MongoClient,
namespace: MongoDBNamespace,
pipeline: Document[] = [],
options: AggregateOptions & Abortable = {}
) {
super(client, namespace, options);
this.pipeline = pipeline;
this.aggregateOptions = options;
const lastStage: Document | undefined = this.pipeline[this.pipeline.length - 1];
if (
this.cursorOptions.timeoutMS != null &&
this.cursorOptions.timeoutMode === CursorTimeoutMode.ITERATION &&
(lastStage?.$merge != null || lastStage?.$out != null)
)
throw new MongoAPIError('Cannot use $out or $merge stage with ITERATION timeoutMode');
}
clone(): AggregationCursor<TSchema> {
const clonedOptions = mergeOptions({}, this.aggregateOptions);
delete clonedOptions.session;
return new AggregationCursor(this.client, this.namespace, this.pipeline, {
...clonedOptions
});
}
override map<T>(transform: (doc: TSchema) => T): AggregationCursor<T> {
return super.map(transform) as AggregationCursor<T>;
}
/** @internal */
async _initialize(session: ClientSession): Promise<InitialCursorResponse> {
const options = {
...this.aggregateOptions,View on GitHub (pinned to 3366c21a63)
Solutions
- Omit timeoutMode (or set it to 'cursorLifetime') when the pipeline ends with $out/$merge
- Remove timeoutMS for $out/$merge pipelines, or wrap the whole operation in your own Promise.race timeout
- If you need a per-batch bound, restructure the pipeline so the write stage is not the terminal stage
Example fix
// before
coll.aggregate([{ ... }, { $out: 'result' }], { timeoutMS: 5000, timeoutMode: 'iteration' });
// after
coll.aggregate([{ ... }, { $out: 'result' }], { timeoutMS: 5000 }); // LIFETIME (default) Defensive patterns
Strategy: validation
Validate before calling
function safeAggregate(coll, pipeline, opts) {
const last = pipeline[pipeline.length - 1];
const hasWriteStage = last && (last.$out != null || last.$merge != null);
if (opts?.timeoutMS != null && opts?.timeoutMode === 'iteration' && hasWriteStage) {
const { timeoutMode, ...rest } = opts;
return coll.aggregate(pipeline, rest); // drop iteration mode
}
return coll.aggregate(pipeline, opts);
} Type guard
const isWriteStage = (s) => s != null && (s.$out != null || s.$merge != null); const canUseIterationMode = (pipeline) => !isWriteStage(pipeline[pipeline.length - 1]);
Prevention
- Do not combine timeoutMode:'iteration' with $out/$merge
- Default to 'cursorLifetime' (or omit timeoutMode) for materialization pipelines
- Validate the terminal stage before constructing the cursor
When it happens
Trigger: collection.aggregate(pipeline, { timeoutMS: N, timeoutMode: 'iteration' }) where pipeline ends with { $out: 'coll' } or { $merge: ... }. Also triggered if you pass timeoutMS without timeoutMode on a non-tailable aggregation, because the driver defaults non-tailable+timeoutMS to LIFETIME — but explicitly setting 'iteration' with $out/$merge is the direct hit.
Common situations: Building a materialized view with $out/$merge under a global timeout policy; inheriting timeoutMS from a shared options object and forcing iteration mode.
Related errors
- timeoutMS cannot be used with explain when explain is specif
- Server reported a timeout error
- timeoutMS cannot be used with explain when explain is specif
- A change stream document has been received that lacks a resu
- [Azure KMS] ${error.message}
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/edf80cdfbadc4f81.json.
Report an issue: GitHub.