mongodb/node-mongodb-native · error · MongoChangeStreamError
A change stream document has been received that lacks a resu
Error message
A change stream document has been received that lacks a resume token (_id).
What it means
Thrown as a MongoChangeStreamError when a change document is received from the server but does not contain an _id field. The _id is the resume token that the driver needs to cache so it can resume the stream after a disconnect. Without it, the driver cannot guarantee at-least-once delivery and rejects the document.
Source
Thrown at src/change_stream.ts:997
this.cursorStream?.destroy();
this.cursorStream = undefined;
}
/** @internal */
private _processChange(change: TChange | null): TChange {
if (this.isClosed) {
// TODO(NODE-3485): Replace with MongoChangeStreamClosedError
throw new MongoAPIError(CHANGESTREAM_CLOSED_ERROR);
}
// a null change means the cursor has been notified, implicitly closing the change stream
if (change == null) {
// TODO(NODE-3485): Replace with MongoChangeStreamClosedError
throw new MongoRuntimeError(CHANGESTREAM_CLOSED_ERROR);
}
if (change && !change._id) {
throw new MongoChangeStreamError(NO_RESUME_TOKEN_ERROR);
}
// cache the resume token
this.cursor.cacheResumeToken(change._id);
// wipe the startAtOperationTime if there was one so that there won't be a conflict
// between resumeToken and startAtOperationTime if we need to reconnect the cursor
this.options.startAtOperationTime = undefined;
return change;
}
/** @internal */
private _processErrorStreamMode(changeStreamError: AnyError, cursorInitialized: boolean) {
// If the change stream has been closed explicitly, do not process error.
if (this.isClosed) return;
if (View on GitHub (pinned to 3366c21a63)
Solutions
- Inspect the pipeline passed to watch(); ensure no stage removes or renames the change document's _id field.
- If you must transform documents, do so in your application after receiving the change, not in the $changeStream pipeline.
- Upgrade mongod to a patched version if you have confirmed the pipeline is correct and the server is omitting _id.
Example fix
// before
const cs = collection.watch([
{ $project: { _id: 0, fullDocument: 1 } } // strips resume token
]);
// after
const cs = collection.watch([]);
cs.on('change', change => {
const { fullDocument } = change; // transform in app code
}); Defensive patterns
Strategy: validation
Validate before calling
// Ensure the watch pipeline does not strip _id
function assertPipelinePreservesResumeToken(pipeline) {
for (const stage of pipeline) {
if (stage.$project && stage.$project._id === 0) throw new Error('pipeline removes resume token _id');
if (stage.$unset && (stage.$unset.includes('_id'))) throw new Error('pipeline removes resume token _id');
}
} Type guard
// Not applicable: validates aggregation stage shape rather than a TS type.
Try / catch
cs.on('error', err => {
if (err instanceof MongoChangeStreamError && /lacks a resume token/.test(err.message)) {
// audit and fix the pipeline, then reopen
} else throw err;
}); Prevention
- Keep the $changeStream pipeline free of stages that drop _id.
- Transform change documents in application code, not in the watch pipeline.
- Add a test asserting the watch pipeline does not project away _id.
When it happens
Trigger: A change document lacking _id reaches _processChange(); typically caused by a malformed aggregation pipeline that strips _id (e.g. a $project stage that excludes it), or a non-standard upstream stage in the pipeline passed to collection.watch().
Common situations: Adding a $project/$unset stage to the watch pipeline that removes the _id field; using $replaceRoot with a document that drops _id; server bugs in older versions emitting tokenless changes.
Related errors
- ChangeStream cannot be used as an EventEmitter after being u
- ChangeStream cannot be used as an iterator after being used
- ChangeStream is closed
- Server reported a timeout error
- Argument "pipeline" must be an array of aggregation stages
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/87d654e55906092c.json.
Report an issue: GitHub.