RocketChat/Rocket.Chat · info

Error dropping redundant indexes, continuing...

Error message

Error dropping redundant indexes, continuing...

What it means

Migration v312 drops four single-field indexes made redundant by compound ones. Note the code shape: Promise.allSettled never rejects, so the surrounding try/catch (and this console.warn) is effectively dead code — individual dropIndex failures (index absent, missing privilege) are captured as rejected results inside the fulfilled array and silently ignored. The migration continues regardless, which is intentional: leftover redundant indexes only cost minor write overhead.

Source

Thrown at apps/meteor/server/startup/migrations/v312.ts:16

import { LivechatRooms, Rooms, Subscriptions, Users } from '@rocket.chat/models';

import { addMigration } from '../../lib/migrations';

addMigration({
	version: 312,
	async up() {
		try {
			await Promise.allSettled([
				LivechatRooms.col.dropIndex('v.token_1'),
				Rooms.col.dropIndex('t_1'),
				Subscriptions.col.dropIndex('rid_1'),
				Users.col.dropIndex('active_1'),
			]);
		} catch (error: unknown) {
			console.warn('Error dropping redundant indexes, continuing...');
			console.warn(error);
		}
	},
});

View on GitHub (pinned to b2c16d5842)

Solutions

  1. No action required for correctness — redundant indexes remaining only adds minor write overhead
  2. To actually clean up, connect with sufficient privileges and drop 'LivechatRooms v.token_1', 'Rooms t_1', 'Subscriptions rid_1', 'Users active_1' manually
  3. If you maintain this code, log the allSettled results instead of the unreachable catch

Example fix

// before: try/catch around Promise.allSettled never fires
try {
	await Promise.allSettled([Rooms.col.dropIndex('t_1')]);
} catch (error) {
	console.warn('Error dropping redundant indexes, continuing...', error);
}
// after: inspect each outcome explicitly
const results = await Promise.allSettled([Rooms.col.dropIndex('t_1')]);
for (const result of results) {
	if (result.status === 'rejected') console.warn('dropIndex failed:', result.reason);
}
Defensive patterns

Strategy: validation

Validate before calling

// drop only indexes that actually exist
async function dropIndexIfExists(collection: { col: { dropIndex(name: string): Promise<unknown>; listIndexes(): { toArray(): Promise<{ name?: string }[]> } } }, name: string) {
	const indexes = await collection.col.listIndexes().toArray();
	if (indexes.some((idx) => idx.name === name)) {
		await collection.col.dropIndex(name);
	}
}

Try / catch

const results = await Promise.allSettled([Rooms.col.dropIndex('t_1')]);
for (const result of results) {
	if (result.status === 'rejected') console.warn('dropIndex failed:', result.reason);
}

Prevention

When it happens

Trigger: Re-running the migration after a partial run (MongoDB returns IndexNotFound / ns not found); database user lacking dropIndex privilege on managed MongoDB; deployments where indexes were renamed or never existed.

Common situations: Restored backups with differing index sets; Atlas/managed MongoDB roles restricting index operations; manually re-run migrations.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/7a5a2932a103d171. Report an issue: GitHub.