Skip to content

Commit 0fa4f21

Browse files
fix(credentials): scope inner duplicate re-check to service_account
OAuth dedupes by accountId, env_* by envKey — both have DB-level partial unique indexes that surface as 23505. The previous inner re-check fired for all types and always threw DuplicateCredentialError, which mapped to 'duplicate_display_name' in the UI even when the real conflict was a duplicate OAuth account or env key. Restrict the in-tx re-check to service_account (the only type without a DB-level index) and let the 23505 handler emit a generic message for everything else.
1 parent 40d7f8b commit 0fa4f21

1 file changed

Lines changed: 12 additions & 15 deletions

File tree

apps/sim/app/api/credentials/route.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -505,21 +505,18 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
505505
.limit(1)
506506

507507
await db.transaction(async (tx) => {
508-
// Race-safety re-check: the outer findExistingCredentialBySource ran outside
509-
// the transaction. Service_account rows have no DB-level unique index on
510-
// (workspaceId, providerId, displayName), so a concurrent request could
511-
// have inserted a duplicate after our outer check but before this insert.
512-
// Re-check here and abort the tx if so. The catch maps this to a 409.
513-
const innerExisting = await findExistingCredentialBySourceTx(tx, {
514-
workspaceId,
515-
type,
516-
accountId: resolvedAccountId,
517-
envKey: resolvedEnvKey,
518-
envOwnerUserId: resolvedEnvOwnerUserId,
519-
displayName: resolvedDisplayName,
520-
providerId: resolvedProviderId,
521-
})
522-
if (innerExisting) throw new DuplicateCredentialError()
508+
// service_account has no DB-level unique index on (workspaceId, providerId,
509+
// displayName), so we re-check inside the tx. OAuth/env_* are guarded by
510+
// partial unique indexes and fall through to the 23505 handler below.
511+
if (type === 'service_account') {
512+
const innerExisting = await findExistingCredentialBySourceTx(tx, {
513+
workspaceId,
514+
type,
515+
displayName: resolvedDisplayName,
516+
providerId: resolvedProviderId,
517+
})
518+
if (innerExisting) throw new DuplicateCredentialError()
519+
}
523520

524521
await tx.insert(credential).values({
525522
id: credentialId,

0 commit comments

Comments
 (0)