{"record":{"id":"4bce19293297f059","repo":"hcengineering/platform","slug":"integrationsecretalreadyexists","errorCode":"IntegrationSecretAlreadyExists","errorMessage":"IntegrationSecretAlreadyExists","messagePattern":"IntegrationSecretAlreadyExists","errorType":"exception","errorClass":"PlatformError","httpStatus":null,"severity":"error","filePath":"server/account/src/serviceOperations.ts","lineNumber":813,"sourceCode":"    kind == null ||\n    kind === '' ||\n    socialId == null ||\n    socialId === '' ||\n    workspaceUuid === undefined ||\n    key == null\n  ) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))\n  }\n\n  const existingIntegration = await findExistingIntegration(account, db, params, extra)\n  if (existingIntegration == null) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {}))\n  }\n\n  const secretKey: IntegrationSecretKey = { socialId, kind, workspaceUuid, key }\n  const existingSecret = await db.integrationSecret.findOne(secretKey)\n  if (existingSecret != null) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationSecretAlreadyExists, {}))\n  }\n\n  await db.integrationSecret.insertOne({ ...secretKey, secret })\n}\n\nexport async function updateIntegrationSecret (\n  ctx: MeasureContext,\n  db: AccountDB,\n  branding: Branding | null,\n  token: string,\n  params: IntegrationSecret\n): Promise<void> {\n  const { extra, account } = decodeTokenVerbose(ctx, token)\n  const { socialId, kind, workspaceUuid, key, secret } = params\n  if (\n    kind == null ||\n    kind === '' ||\n    socialId == null ||","sourceCodeStart":795,"sourceCodeEnd":831,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/account/src/serviceOperations.ts#L795-L831","documentation":"addIntegrationSecret throws IntegrationSecretAlreadyExists when a secret with the exact key tuple (socialId, kind, workspaceUuid, key) already exists in the integrationSecret collection. The account service treats secret keys as unique and refuses to overwrite silently. This prevents accidentally clobbering an existing integration secret.","triggerScenarios":"Calling addIntegrationSecret twice with the same {socialId, kind, workspaceUuid, key} without first deleting or updating the existing secret.","commonSituations":"Re-running an integration setup script after a partial failure; retry logic that repeats addIntegrationSecret on timeouts; migrating integrations without deduplicating keys first.","solutions":["Check existence first with getIntegrationSecret or listIntegrationsSecrets and skip if already present","Delete the existing secret via deleteIntegrationSecret, then re-add it","Use updateIntegrationSecret instead of addIntegrationSecret to change the secret value","Use a fresh `key` if the new secret is semantically different"],"exampleFix":"// before\nawait client.addIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token', secret })\n// after\nconst existing = await client.getIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token' })\nif (existing == null) {\n  await client.addIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token', secret })\n} else {\n  await client.updateIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token', secret })\n}","handlingStrategy":"validation","validationCode":"const existing = await client.getIntegrationSecret({ socialId, kind, workspaceUuid, key })\nif (existing != null) throw new Error(`Integration secret '${key}' already exists`)","typeGuard":null,"tryCatchPattern":"try {\n  await client.addIntegrationSecret({ socialId, kind, workspaceUuid, key, secret })\n} catch (err) {\n  if (isStatusError(err, 'account.status.IntegrationSecretAlreadyExists')) {\n    await client.updateIntegrationSecret({ socialId, kind, workspaceUuid, key, secret })\n  } else { throw err }\n}","preventionTips":["Always get-before-add for integration secrets","Use update for changing values, add only for new keys","Make setup scripts idempotent by checking existence first"],"tags":["account-service","integration-secret","duplicate-key"],"backgroundTag":"duplicate-record-conflict","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}