{"record":{"id":"44adead5331c0466","repo":"calcom/cal.diy","slug":"no-setup-needed","errorCode":null,"errorMessage":"No setup needed.","messagePattern":"No setup needed\\.","errorType":"http","errorClass":"HttpError","httpStatus":400,"severity":"info","filePath":"apps/web/app/api/auth/setup/route.ts","lineNumber":31,"sourceCode":"import { IdentityProvider } from \"@calcom/prisma/enums\";\nimport { CreationSource } from \"@calcom/prisma/enums\";\n\nconst querySchema = z.object({\n  username: z\n    .string()\n    .refine((val) => val.trim().length >= 1, { message: \"Please enter at least one character\" }),\n  full_name: z.string().min(3, \"Please enter at least 3 characters\"),\n  email_address: z.string().regex(emailRegex, { message: \"Please enter a valid email\" }),\n  password: z.string().refine((val) => isPasswordValid(val.trim(), false, true), {\n    message:\n      \"The password must be a minimum of 15 characters long containing at least one number and have a mixture of uppercase and lowercase letters\",\n  }),\n});\n\nasync function handler(req: NextRequest) {\n  const userCount = await prisma.user.count();\n  if (userCount !== 0) {\n    throw new HttpError({ statusCode: 400, message: \"No setup needed.\" });\n  }\n  const body = await parseRequestData(req);\n\n  const parsedQuery = querySchema.safeParse(body);\n  if (!parsedQuery.success) {\n    throw new HttpError({ statusCode: 422, message: parsedQuery.error.message });\n  }\n\n  const username = slugify(parsedQuery.data.username.trim());\n  const userEmail = parsedQuery.data.email_address.toLowerCase();\n\n  const hashedPassword = await hashPassword(parsedQuery.data.password);\n\n  await prisma.user.create({\n    data: {\n      username,\n      email: userEmail,\n      password: { create: { hash: hashedPassword } },","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/web/app/api/auth/setup/route.ts#L13-L49","documentation":"Thrown by the /api/auth/setup route handler (HttpError, HTTP 400) when prisma.user.count() is non-zero, meaning the instance already has at least one user and first-run setup is therefore closed. It is a hard gate before any input is parsed.","triggerScenarios":"POST /api/auth/setup on an already-initialized instance; an automated deploy script that always hits setup; retrying setup after a partial first run that already created the admin user.","commonSituations":"CI/CD running the setup step unconditionally, re-running setup after a failed-but-committed first user, environment restored from a DB snapshot that already contains users.","solutions":["Skip the setup call when the instance is already initialized (treat this 400 as 'success: already done').","In provisioning scripts, check GET /api/auth/setup or a health endpoint before attempting creation.","If re-seeding is truly required, truncate users in the target DB first (non-production only)."],"exampleFix":"// before\nawait fetch('/api/auth/setup', { method: 'POST', body: payload });\n\n// after\nconst res = await fetch('/api/auth/setup', { method: 'POST', body: payload });\nif (res.status === 400 && (await res.json()).message === 'No setup needed.') {\n  // instance already initialized; nothing to do\n  return;\n}","handlingStrategy":"validation","validationCode":"// Provisioning helper: only attempt setup if no users exist yet\nconst status = await fetch('/api/auth/setup-status').then(r => r.json());\nif (status.userCount > 0) {\n  console.log('Instance already initialized; skipping setup.');\n  return;\n}\nawait fetch('/api/auth/setup', { method: 'POST', body: JSON.stringify(adminPayload) });","typeGuard":null,"tryCatchPattern":"try {\n  await fetch('/api/auth/setup', { method: 'POST', body });\n} catch (e) {\n  if (e instanceof HttpError && e.statusCode === 400 && /No setup needed/.test(e.message)) {\n    return; // already initialized\n  }\n  throw e;\n}","preventionTips":["Make setup scripts idempotent and treat 'No setup needed' as success.","Gate CI setup steps on a user-count precondition.","Avoid re-running setup after the first user is committed."],"tags":["setup","auth","initialization","first-run"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}