{"record":{"id":"5cee75a5e36e807d","repo":"toeverything/AFFiNE","slug":"password-required","errorCode":"password_required","errorMessage":"Password is required.","messagePattern":"Password is required\\.","errorType":"exception","errorClass":"PasswordRequired","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/core/selfhost/controller.ts","lineNumber":49,"sourceCode":"    private readonly mutex: Mutex,\n    private readonly server: ServerService\n  ) {}\n\n  @Public()\n  @Post('/create-admin-user')\n  async createAdmin(\n    @Req() req: Request,\n    @Res() res: Response,\n    @Body() input: CreateUserInput\n  ) {\n    if (await this.server.initialized()) {\n      throw new ActionForbidden('First user already created');\n    }\n\n    validators.assertValidEmail(input.email);\n\n    if (!input.password) {\n      throw new PasswordRequired();\n    }\n\n    validators.assertValidPassword(\n      input.password,\n      this.config.auth.passwordRequirements\n    );\n\n    await using lock = await this.mutex.acquire('createFirstAdmin');\n\n    if (!lock) {\n      throw new InternalServerError();\n    }\n    const user = await this.models.user.create({\n      name: input.name || undefined,\n      email: input.email,\n      password: input.password,\n      registered: true,\n    });","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/2af30773aecd567f09b346e7b72fc69143144057/packages/backend/server/src/core/selfhost/controller.ts#L31-L67","documentation":"PasswordRequired thrown at packages/backend/server/src/core/selfhost/controller.ts:48 when the create-admin request body has no password (falsy). It is a plain required-field guard that runs before assertValidPassword applies the configured password policy.","triggerScenarios":"POST /create-admin-user with password omitted, an empty string, or a body key typo such as pwd/pass.","commonSituations":"Setup form not binding the password input, a proxy renaming JSON fields, or provisioning scripts that only send email/name.","solutions":["Send a non-empty password field in the JSON body.","Ensure the value survives any proxy/serializer untouched."],"exampleFix":"// before\nawait api.createAdmin({ name, email }); // password missing\n\n// after\nawait api.createAdmin({ name, email, password }); // non-empty string","handlingStrategy":"validation","validationCode":"if (typeof password !== 'string' || password.length === 0) {\n  return setFieldError('password', 'Password is required.');\n}","typeGuard":"const isPasswordRequired = (e: unknown): e is PasswordRequired =>\n  e instanceof PasswordRequired;","tryCatchPattern":"try {\n  await api.createAdmin({ name, email, password });\n} catch (e) {\n  if (e instanceof PasswordRequired) return setFieldError('password', e.message);\n  throw e;\n}","preventionTips":["Require the password field client-side before enabling submit.","Validate against the same passwordRequirements config the server enforces."],"tags":["selfhost","validation","password","setup"],"backgroundTag":"missing-required-argument","analyzedSha":"2af30773aecd567f09b346e7b72fc69143144057","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}