{"record":{"id":"0946e99251caa578","repo":"Dokploy/dokploy","slug":"conflict-0946e9","errorCode":"CONFLICT","errorMessage":"Service with this 'AppName' already exists","messagePattern":"Service with this 'AppName' already exists","errorType":"exception","errorClass":"TRPCError","httpStatus":409,"severity":"error","filePath":"packages/server/src/services/mysql.ts","lineNumber":25,"sourceCode":"} from \"@dokploy/server/db/schema\";\nimport { generatePassword } from \"@dokploy/server/templates\";\nimport { buildMysql } from \"@dokploy/server/utils/databases/mysql\";\nimport { pullImage } from \"@dokploy/server/utils/docker/utils\";\nimport { execAsyncRemote } from \"@dokploy/server/utils/process/execAsync\";\nimport { TRPCError } from \"@trpc/server\";\nimport { eq, getTableColumns } from \"drizzle-orm\";\nimport { quote } from \"shell-quote\";\nimport type { z } from \"zod\";\nimport { validUniqueServerAppName } from \"./project\";\n\nexport type MySql = typeof mysql.$inferSelect;\n\nexport const createMysql = async (input: z.infer<typeof apiCreateMySql>) => {\n\tconst appName = buildAppName(\"mysql\", input.appName);\n\n\tconst valid = await validUniqueServerAppName(appName);\n\tif (!valid) {\n\t\tthrow new TRPCError({\n\t\t\tcode: \"CONFLICT\",\n\t\t\tmessage: \"Service with this 'AppName' already exists\",\n\t\t});\n\t}\n\n\tconst newMysql = await db\n\t\t.insert(mysql)\n\t\t.values({\n\t\t\t...input,\n\t\t\tdatabasePassword: input.databasePassword\n\t\t\t\t? input.databasePassword\n\t\t\t\t: generatePassword(),\n\t\t\tdatabaseRootPassword: input.databaseRootPassword\n\t\t\t\t? input.databaseRootPassword\n\t\t\t\t: generatePassword(),\n\t\t\tappName,\n\t\t})\n\t\t.returning()","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/packages/server/src/services/mysql.ts#L7-L43","documentation":"createMysql builds a namespaced app name via buildAppName('mysql', appName) and validates uniqueness with validUniqueServerAppName across the target server. If an app (any service) already uses that name on that server, a CONFLICT is thrown before any DB insert.","triggerScenarios":"Creating a mysql service with an appName that collides with an existing mysql/postgres/redis/app on the same server; creating the same service twice because the first request was double-submitted.","commonSituations":"Double-clicking 'Create' in the UI, retrying after a timeout when the first create actually succeeded, re-running a terraform/script without idempotency checks.","solutions":["Choose a different appName for the new mysql service","List existing services on that server to confirm the collision and reuse or delete the existing one","Make automation idempotent: check existence by appName before creating","Guard against double submission in the UI"],"exampleFix":"// before\nawait createMysql({ appName: \"db\", serverId });\n// after\nconst exists = (await listMySql(serverId)).some(m => m.appName.includes(\"mysql-db\"));\nif (!exists) await createMysql({ appName: \"db\", serverId });","handlingStrategy":"validation","validationCode":"const dup = (await listServices(serverId)).some(s => s.appName === buildName(\"mysql\", appName));\nif (dup) throw new Error(\"appName already in use on this server\");","typeGuard":null,"tryCatchPattern":"try { await createMysql(input); } catch (e) { if (e instanceof TRPCError && e.code === \"CONFLICT\") promptRename(); else throw e; }","preventionTips":["Generate unique appNames in automation (suffix with env/timestamp)","Disable submit button while pending"],"tags":["mysql","conflict","unique-constraint","app-name"],"backgroundTag":"duplicate-resource-name","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}