hcengineering/platform · error · PlatformError

IntegrationSecretAlreadyExists

IntegrationSecretAlreadyExists

Error message

IntegrationSecretAlreadyExists

What it means

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.

Source

Thrown at server/account/src/serviceOperations.ts:813

    kind == null ||
    kind === '' ||
    socialId == null ||
    socialId === '' ||
    workspaceUuid === undefined ||
    key == null
  ) {
    throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
  }

  const existingIntegration = await findExistingIntegration(account, db, params, extra)
  if (existingIntegration == null) {
    throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {}))
  }

  const secretKey: IntegrationSecretKey = { socialId, kind, workspaceUuid, key }
  const existingSecret = await db.integrationSecret.findOne(secretKey)
  if (existingSecret != null) {
    throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationSecretAlreadyExists, {}))
  }

  await db.integrationSecret.insertOne({ ...secretKey, secret })
}

export async function updateIntegrationSecret (
  ctx: MeasureContext,
  db: AccountDB,
  branding: Branding | null,
  token: string,
  params: IntegrationSecret
): Promise<void> {
  const { extra, account } = decodeTokenVerbose(ctx, token)
  const { socialId, kind, workspaceUuid, key, secret } = params
  if (
    kind == null ||
    kind === '' ||
    socialId == null ||

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check existence first with getIntegrationSecret or listIntegrationsSecrets and skip if already present
  2. Delete the existing secret via deleteIntegrationSecret, then re-add it
  3. Use updateIntegrationSecret instead of addIntegrationSecret to change the secret value
  4. Use a fresh `key` if the new secret is semantically different

Example fix

// before
await client.addIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token', secret })
// after
const existing = await client.getIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token' })
if (existing == null) {
  await client.addIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token', secret })
} else {
  await client.updateIntegrationSecret({ socialId, kind, workspaceUuid, key: 'token', secret })
}
Defensive patterns

Strategy: validation

Validate before calling

const existing = await client.getIntegrationSecret({ socialId, kind, workspaceUuid, key })
if (existing != null) throw new Error(`Integration secret '${key}' already exists`)

Try / catch

try {
  await client.addIntegrationSecret({ socialId, kind, workspaceUuid, key, secret })
} catch (err) {
  if (isStatusError(err, 'account.status.IntegrationSecretAlreadyExists')) {
    await client.updateIntegrationSecret({ socialId, kind, workspaceUuid, key, secret })
  } else { throw err }
}

Prevention

When it happens

Trigger: Calling addIntegrationSecret twice with the same {socialId, kind, workspaceUuid, key} without first deleting or updating the existing secret.

Common situations: Re-running an integration setup script after a partial failure; retry logic that repeats addIntegrationSecret on timeouts; migrating integrations without deduplicating keys first.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/4bce19293297f059. Report an issue: GitHub.