hcengineering/platform · error · PlatformError

IntegrationSecretNotFound

IntegrationSecretNotFound

Error message

IntegrationSecretNotFound

What it means

updateIntegrationSecret looks up the existing secret by (socialId, kind, workspaceUuid, key) and throws IntegrationSecretNotFound when no record matches. The service only updates existing secrets; it never upserts.

Source

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

    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.IntegrationSecretNotFound, {}))
  }

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

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

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Call addIntegrationSecret to create the secret if it should exist, or getIntegrationSecret first to confirm presence
  2. Verify the exact `key` string matches the one used at creation time
  3. Confirm the secret was not deleted by another process (check deleteIntegrationSecret callers)
  4. Fall back to upsert logic: try get, add if missing, else update

Example fix

// before
await client.updateIntegrationSecret({ 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: try-catch

Validate before calling

const existing = await client.getIntegrationSecret({ socialId, kind, workspaceUuid, key })
if (existing == null) throw new Error(`Secret '${key}' does not exist yet; use addIntegrationSecret`)

Try / catch

try {
  await client.updateIntegrationSecret(params)
} catch (err) {
  if (isStatusError(err, 'account.status.IntegrationSecretNotFound')) {
    await client.addIntegrationSecret({ ...params }) // upsert fallback
  } else { throw err }
}

Prevention

When it happens

Trigger: Calling updateIntegrationSecret for a key that was never added via addIntegrationSecret, or after the secret was already deleted.

Common situations: Key string mismatch (e.g. 'github-token' vs 'token'); secret stored under a different workspace; attempting update in a fresh environment where add was never run; double-delete race.

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


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