{"record":{"id":"9ab1ab4ea519b109","repo":"RocketChat/Rocket.Chat","slug":"invalid-integration","errorCode":"invalid_integration","errorMessage":"[methods] updateOutgoingIntegration -> integration not found","messagePattern":"\\[methods\\] updateOutgoingIntegration -> integration not found","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/integrations/outgoing/updateOutgoingIntegration.ts","lineNumber":52,"sourceCode":"\t}\n\n\tlet currentIntegration: IIntegration | null;\n\n\tif (await hasPermissionAsync(userId, 'manage-outgoing-integrations')) {\n\t\tcurrentIntegration = await Integrations.findOneById(integrationId);\n\t} else if (await hasPermissionAsync(userId, 'manage-own-outgoing-integrations')) {\n\t\tcurrentIntegration = await Integrations.findOne({\n\t\t\t'_id': integrationId,\n\t\t\t'_createdBy._id': userId,\n\t\t});\n\t} else {\n\t\tthrow new Meteor.Error('not_authorized', 'Unauthorized', {\n\t\t\tmethod: 'updateOutgoingIntegration',\n\t\t});\n\t}\n\n\tif (!currentIntegration) {\n\t\tthrow new Meteor.Error('invalid_integration', '[methods] updateOutgoingIntegration -> integration not found');\n\t}\n\n\tconst oldScriptEngine = currentIntegration.scriptEngine;\n\tconst scriptEngine = integration.scriptEngine ?? oldScriptEngine ?? 'isolated-vm';\n\tif (\n\t\tintegration.script?.trim() &&\n\t\t(scriptEngine !== oldScriptEngine || integration.script?.trim() !== currentIntegration.script?.trim())\n\t) {\n\t\twrapExceptions(() => validateScriptEngine(scriptEngine)).catch((e) => {\n\t\t\tthrow new Meteor.Error(e.message);\n\t\t});\n\t}\n\n\tconst isFrozen = isScriptEngineFrozen(scriptEngine);\n\n\tconst updatedIntegration = await Integrations.findOneAndUpdate(\n\t\t{ _id: integrationId },\n\t\t{","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/integrations/outgoing/updateOutgoingIntegration.ts#L34-L70","documentation":"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.","triggerScenarios":"Updating a deleted or mistyped integrationId; owning-only permissions while updating another user's integration; stale UI list referencing a removed integration.","commonSituations":"Concurrent admins editing/removing the same webhook; copied ids with whitespace or truncation; permission model misunderstanding where manage-own silently hides other users' integrations.","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"],"exampleFix":"// before\nawait Meteor.callAsync('updateOutgoingIntegration', staleId, payload);\n\n// after\nconst res = await fetch('/api/v1/integrations.list?type=webhook-outgoing', { headers });\nconst { integrations } = await res.json();\nconst current = integrations.find((i) => i._id === staleId);\nif (!current) throw new Error('Integration no longer exists');\nawait Meteor.callAsync('updateOutgoingIntegration', current._id, payload);","handlingStrategy":"validation","validationCode":"// confirm existence and ownership before updating\nconst res = await fetch('/api/v1/integrations.list?type=webhook-outgoing', { headers });\nconst { integrations } = await res.json();\nconst target = integrations.find((i) => i._id === integrationId);\nif (!target) throw new Error('Integration not found');\nif (!canManageAll && target._createdBy?._id !== uid) throw new Error('Not your integration');","typeGuard":"const isUpdatableIntegration = (\n  i: IIntegration | null | undefined,\n  uid: string,\n  manageAll: boolean,\n): i is IIntegration => !!i && (manageAll || i._createdBy?._id === uid);","tryCatchPattern":"try {\n  await Meteor.callAsync('updateOutgoingIntegration', id, payload);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'invalid_integration') {\n    // record gone or not owned: refresh the list, do not retry the stale id\n    return;\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["integrations","not-found","meteor-methods"],"backgroundTag":"resource-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}