{"record":{"id":"e205ec1b2c2dd006","repo":"Dokploy/dokploy","slug":"conflict-e205ec","errorCode":"CONFLICT","errorMessage":"A vault provider named \"${input.name}\" already exists in this organization","messagePattern":"A vault provider named \"(.+?)\" already exists in this organization","errorType":"exception","errorClass":"TRPCError","httpStatus":409,"severity":"warning","filePath":"packages/server/src/services/vault-provider.ts","lineNumber":124,"sourceCode":"\t\t\t\tname: input.name,\n\t\t\t\tproviderType: input.config.providerType,\n\t\t\t\tconfig: input.config,\n\t\t\t\tassignments: input.assignments,\n\t\t\t\torganizationId,\n\t\t\t})\n\t\t\t.returning()\n\t\t\t.then((value) => value[0]);\n\n\t\tif (!newProvider) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: \"BAD_REQUEST\",\n\t\t\t\tmessage: \"Error creating the vault provider\",\n\t\t\t});\n\t\t}\n\t\treturn newProvider;\n\t} catch (error) {\n\t\tif (isUniqueNameViolation(error)) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\tmessage: `A vault provider named \"${input.name}\" already exists in this organization`,\n\t\t\t});\n\t\t}\n\t\tthrow error;\n\t}\n};\n\nexport const findVaultProviderById = async (vaultProviderId: string) => {\n\tconst provider = await db.query.vaultProvider.findFirst({\n\t\twhere: eq(vaultProvider.vaultProviderId, vaultProviderId),\n\t});\n\tif (!provider) {\n\t\tthrow new TRPCError({\n\t\t\tcode: \"NOT_FOUND\",\n\t\t\tmessage: \"Vault provider not found\",\n\t\t});\n\t}","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/packages/server/src/services/vault-provider.ts#L106-L142","documentation":"The database raised a unique-constraint violation (detected via isUniqueNameViolation) while inserting a vault provider, meaning another provider in the same organization already uses the requested name. Vault provider names are unique per organization, so the insert is rejected and rethrown as a CONFLICT.","triggerScenarios":"Calling createVaultProvider with a name that already exists for the same organizationId — typically a double-submit, retry after a timeout, or picking an existing name like 'default'.","commonSituations":"Duplicate form submissions, concurrent creation requests, retries after network errors, or assuming names are globally scoped instead of per-organization.","solutions":["List existing providers for the organization and pick a different name","Handle 409 CONFLICT in the UI by prompting for a new name instead of retrying blindly","Add idempotency: check for an existing provider with that name before inserting (or reuse it)","Debounce/disable the submit button to prevent double-submits"],"exampleFix":"// before\nawait createVaultProvider({ name: \"prod-vault\", ... });\n\n// after\nconst existing = await db.query.vaultProvider.findFirst({\n  where: and(eq(vaultProvider.name, input.name), eq(vaultProvider.organizationId, organizationId)),\n});\nif (existing) return existing; // idempotent reuse\nawait createVaultProvider({ name: \"prod-vault-2\", ... });","handlingStrategy":"validation","validationCode":"const existing = await db.query.vaultProvider.findFirst({ where: and(eq(vaultProvider.name, input.name), eq(vaultProvider.organizationId, orgId)) });\nif (existing) return existing;","typeGuard":"const isConflictError = (e: unknown): boolean => e instanceof TRPCError && e.code === 'CONFLICT';","tryCatchPattern":"try { await createVaultProvider(input); } catch (e) { if (e instanceof TRPCError && e.code === 'CONFLICT') { promptUserForNewName(input.name); return; } throw e; }","preventionTips":["Check name availability in the org before submit","Disable submit button while request is pending (prevents double-submit)","Treat 409 as a prompt, not a retry signal"],"tags":["vault","conflict","unique-constraint","drizzle","trpc"],"backgroundTag":"unique-constraint-violation","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}