RocketChat/Rocket.Chat · error · Meteor.Error
invalid_integration
invalid_integration
Error message
[methods] updateOutgoingIntegration -> integration not found
What it means
Thrown when the permission branch succeeded but the integration lookup returned null: either the id does not exist at all, or the caller holds only manage-own-outgoing-integrations and the query's _createdBy._id === userId filter excluded an integration owned by someone else. The code is invalid_integration (with underscores), distinct from error-invalid-integration used by the delete path.
Source
Thrown at apps/meteor/server/meteor-methods/integrations/outgoing/updateOutgoingIntegration.ts:52
}
let currentIntegration: IIntegration | null;
if (await hasPermissionAsync(userId, 'manage-outgoing-integrations')) {
currentIntegration = await Integrations.findOneById(integrationId);
} else if (await hasPermissionAsync(userId, 'manage-own-outgoing-integrations')) {
currentIntegration = await Integrations.findOne({
'_id': integrationId,
'_createdBy._id': userId,
});
} else {
throw new Meteor.Error('not_authorized', 'Unauthorized', {
method: 'updateOutgoingIntegration',
});
}
if (!currentIntegration) {
throw new Meteor.Error('invalid_integration', '[methods] updateOutgoingIntegration -> integration not found');
}
const oldScriptEngine = currentIntegration.scriptEngine;
const scriptEngine = integration.scriptEngine ?? oldScriptEngine ?? 'isolated-vm';
if (
integration.script?.trim() &&
(scriptEngine !== oldScriptEngine || integration.script?.trim() !== currentIntegration.script?.trim())
) {
wrapExceptions(() => validateScriptEngine(scriptEngine)).catch((e) => {
throw new Meteor.Error(e.message);
});
}
const isFrozen = isScriptEngineFrozen(scriptEngine);
const updatedIntegration = await Integrations.findOneAndUpdate(
{ _id: integrationId },
{View on GitHub (pinned to b2c16d5842)
Solutions
- List integrations (GET /v1/integrations.list?type=webhook-outgoing) and confirm the exact _id still exists
- If you hold only manage-own permissions, verify _createdBy._id matches your userId or hand the task to an admin
- Refresh the UI data before retrying so you edit a live record
Example fix
// before
await Meteor.callAsync('updateOutgoingIntegration', staleId, payload);
// after
const res = await fetch('/api/v1/integrations.list?type=webhook-outgoing', { headers });
const { integrations } = await res.json();
const current = integrations.find((i) => i._id === staleId);
if (!current) throw new Error('Integration no longer exists');
await Meteor.callAsync('updateOutgoingIntegration', current._id, payload); Defensive patterns
Strategy: validation
Validate before calling
// confirm existence and ownership before updating
const res = await fetch('/api/v1/integrations.list?type=webhook-outgoing', { headers });
const { integrations } = await res.json();
const target = integrations.find((i) => i._id === integrationId);
if (!target) throw new Error('Integration not found');
if (!canManageAll && target._createdBy?._id !== uid) throw new Error('Not your integration'); Type guard
const isUpdatableIntegration = ( i: IIntegration | null | undefined, uid: string, manageAll: boolean, ): i is IIntegration => !!i && (manageAll || i._createdBy?._id === uid);
Try / catch
try {
await Meteor.callAsync('updateOutgoingIntegration', id, payload);
} catch (err) {
if (err instanceof Meteor.Error && err.error === 'invalid_integration') {
// record gone or not owned: refresh the list, do not retry the stale id
return;
}
throw err;
} Prevention
- Note the underscore spelling invalid_integration — distinct from error-invalid-integration
- Edit only from a freshly loaded integration list
- With manage-own permissions, filter the list to your own integrations
When it happens
Trigger: Updating a deleted or mistyped integrationId; owning-only permissions while updating another user's integration; stale UI list referencing a removed integration.
Common situations: Concurrent admins editing/removing the same webhook; copied ids with whitespace or truncation; permission model misunderstanding where manage-own silently hides other users' integrations.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- error-invalid-integration
- The integration does not exists.
- error-invalid-integration
- error-invalid-integration-history
- error-invalid-room
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/9ab1ab4ea519b109.
Report an issue: GitHub.