RocketChat/Rocket.Chat · error · Meteor.Error
error-cursor-not-found
error-cursor-not-found
Error message
Cursor not found
What it means
mountCursorFromMessage derives the next/previous cursor from a boundary message of the fetched page: _updatedAt for type UPDATED, _deletedAt for DELETED (trash collection). If the boundary message lacks the required timestamp, the server cannot continue pagination and throws Meteor.Error 'error-cursor-not-found'. This is a server-side data-integrity failure, not a client-input error.
Source
Thrown at apps/meteor/server/publications/messages.ts:84
}
if (previous) {
return { query: { $lt: extractTimestampFromCursor(previous) }, options: { ...options, sort: { _updatedAt: -1 } } };
}
return { query: { $gt: new Date(0) }, options };
}
export function mountCursorFromMessage(message: IMessage & { _deletedAt?: Date }, type: 'UPDATED' | 'DELETED'): string {
if (type === 'UPDATED' && message._updatedAt) {
return `${message._updatedAt.getTime()}`;
}
if (type === 'DELETED' && message._deletedAt) {
return `${message._deletedAt.getTime()}`;
}
throw new Meteor.Error('error-cursor-not-found', 'Cursor not found', { method: 'messages/get' });
}
export function mountNextCursor(
messages: IMessage[],
count: number,
type: CursorPaginationType,
next?: string,
previous?: string,
): string | null {
if (messages.length === 0) {
return null;
}
if (previous) {
return mountCursorFromMessage(messages[0], type);
}
if (messages.length <= count && next) {View on GitHub (pinned to b2c16d5842)
Solutions
- Identify the offending documents (messages lacking _updatedAt, trash docs lacking _deletedAt) and backfill the missing timestamps
- Page past the broken boundary by re-fetching without a cursor (lastUpdate mode)
- Report the corrupted range upstream — these fields are set on every normal write, so their absence indicates abnormal data
Defensive patterns
Strategy: try-catch
Try / catch
try {
return await getMessageHistory(rid, fromId, { type, next });
} catch (error) {
if (error instanceof Meteor.Error && error.error === 'error-cursor-not-found') {
// boundary message is missing its timestamp; fall back to lastUpdate-based sync
return await getMessageHistory(rid, fromId, { lastUpdate: new Date(Date.now() - 60_000) });
}
throw error;
} Prevention
- Never write message documents without _updatedAt (or trash docs without _deletedAt) in migrations and imports
- Audit imported data for missing audit timestamps before enabling cursor pagination
- Backfill missing timestamps on legacy documents instead of suppressing the error
When it happens
Trigger: A message document in the result page without _updatedAt, or a trashed document without _deletedAt — legacy documents predating the field, manual database edits, or a partial write that skipped the audit timestamp.
Common situations: Old installations after upgrades; imported data missing audit timestamps; direct Mongo modifications that dropped fields.
Related errors
- Invalid Date
- error-cursor-conflict
- error-type-param-not-supported
- error-type-param-required
- error-invalid-cursor
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/b7ec41932da22efc.
Report an issue: GitHub.