RocketChat/Rocket.Chat · error · Error

Error inserting integration

Error message

Error inserting integration

What it means

A plain Error (not Meteor.Error, no error code) thrown when Integrations.findOne({ _id: insertedId }) returns null immediately after a successful insertOne. It signals a read-after-write inconsistency: the insert reported success but the follow-up read cannot find the document. Because it is not a Meteor.Error, DDP clients in production receive the sanitized 'Internal server error [500]'; the real message appears only in server logs.

Source

Thrown at apps/meteor/server/meteor-methods/integrations/incoming/addIncomingIntegration.ts:177

		if (
			!(await hasAllPermissionAsync(userId, ['manage-incoming-integrations', 'manage-own-incoming-integrations'])) &&
			!(await Subscriptions.findOneByRoomIdAndUserId(record._id, userId, { projection: { _id: 1 } }))
		) {
			throw new Meteor.Error('error-invalid-channel', 'Invalid Channel', {
				method: 'addIncomingIntegration',
			});
		}
	}

	const strippedIntegrationData = removeEmpty(integrationData);

	const { insertedId } = await Integrations.insertOne(strippedIntegrationData);

	const integrationStored = await Integrations.findOne({ _id: insertedId });

	if (!integrationStored) {
		throw new Error('Error inserting integration');
	}
	void notifyOnIntegrationChanged({ ...integrationStored, _id: insertedId }, 'inserted');

	return integrationStored as IIncomingIntegration;
};

Meteor.methods<ServerMethods>({
	async addIncomingIntegration(integration: INewIncomingIntegration): Promise<IIncomingIntegration> {
		methodDeprecationLogger.method('addIncomingIntegration', '9.0.0', '/v1/integrations.create');
		const { userId } = this;

		if (!userId) {
			throw new Meteor.Error('invalid-user', 'Invalid User', {
				method: 'addIncomingIntegration',
			});
		}

		return addIncomingIntegration(userId, integration);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Retry the call once - but first check whether the first attempt actually inserted a record (list integrations) to avoid duplicates
  2. Check replica set health, oplog, and the driver's readPreference; route reads to primary for this path
  3. Look for custom observers/triggers on the integrations collection that delete on insert
  4. If it persists on a stock setup, collect server logs and open a Rocket.Chat core issue

Example fix

// before: single attempt
const integration = await Meteor.callAsync('addIncomingIntegration', payload);
// after: verify-then-retry on the rare read-after-write miss
let integration;
for (let attempt = 0; attempt < 2; attempt++) {
  try {
    integration = await Meteor.callAsync('addIncomingIntegration', payload);
    break;
  } catch (e) {
    if (attempt === 1 || !(e instanceof Meteor.Error)) throw e; // sanitized 500 lands here, real message is in server logs
    const existing = await Meteor.callAsync('listIncomingIntegrations');
    if (existing.integrations?.some((i) => i.name === payload.name)) break; // insert actually succeeded
  }
}
Defensive patterns

Strategy: retry

Try / catch

const createWithRetry = async (integration, attempts = 2) => {
  for (let i = 0; i < attempts; i++) {
    try { return await Meteor.callAsync('addIncomingIntegration', integration); }
    catch (err) {
      if (i === attempts - 1 || err instanceof Meteor.Error) throw err; // sanitized 500 (non Meteor.Error) -> retry once
      const list = await Meteor.callAsync('listIncomingIntegrations');
      if (list.integrations?.some((x) => x.name === integration.name)) return null; // first insert actually landed
    }
  }
};

Prevention

When it happens

Trigger: MongoDB reads routed to a secondary with replication lag (readPreference secondaryPreferred/nearest); an external watcher/trigger deleting the integration between insert and read; a flaky proxy or mongos dropping the read. Extremely rare on a healthy single-node deployment.

Common situations: Self-hosted replica sets with misconfigured read preference; aggressive custom cleanup jobs on the integrations collection; middleware that audits and prunes new documents.

Related errors


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