{"record":{"id":"a6f2871eeb80bda0","repo":"toeverything/AFFiNE","slug":"invalid-email","errorCode":"invalid_email","errorMessage":"An invalid email provided: ${email}","messagePattern":"An invalid email provided: (.+?)","errorType":"exception","errorClass":"InvalidEmail","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/core/auth/controller.ts","lineNumber":97,"sourceCode":"    private readonly config: Config\n  ) {\n    if (env.dev) {\n      // set DNS servers in dev mode\n      // NOTE: some network debugging software uses DNS hijacking\n      // to better debug traffic, but their DNS servers may not\n      // handle the non dns query(like txt, mx) correctly, so we\n      // set a public DNS server here to avoid this issue.\n      setServers(['1.1.1.1', '8.8.8.8']);\n    }\n  }\n\n  @Public()\n  @UseNamedGuard('version')\n  @Post('/preflight')\n  async preflight(@Body() body?: unknown): Promise<PreflightResponse> {\n    const input = AuthPreflightBodySchema.safeParse(body);\n    if (!input.success) {\n      throw new InvalidEmail({ email: 'not provided' });\n    }\n    validators.assertValidEmail(input.data.email);\n\n    return this.authMethods.loginPreflight(input.data.email);\n  }\n\n  @UseNamedGuard('version')\n  @Get('/methods')\n  async boundMethods(@CurrentUser() user: CurrentUser) {\n    return this.authMethods.boundMethods(user.id);\n  }\n\n  @Public()\n  @UseNamedGuard('version', 'captcha')\n  @Post('/sign-in')\n  @Header('content-type', 'application/json')\n  async signIn(\n    @Req() req: Request,","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/core/auth/controller.ts#L79-L115","documentation":"Thrown by the `POST /api/auth/preflight` handler when the request body fails `AuthPreflightBodySchema.safeParse`. The schema is `{ email: z.string().max(320) }.strict()`, so a missing `email` field, an extra unknown field, or a non-string body all fail. The message reports `email: 'not provided'` to distinguish this from a syntactically bad email (which is caught next by `assertValidEmail`). HTTP 400.","triggerScenarios":"Calling `/preflight` with an empty body `{}`, omitting the `email` field, sending `email` as null/number, or including extra fields rejected by `.strict()` (e.g. legacy `captcha` field).","commonSituations":"Frontend form submitted before the email input was filled, a malformed fetch payload, an integration test posting the wrong shape, or a client version mismatch sending fields the strict schema rejects.","solutions":["Send a body that matches `{ email: string }` exactly — no extra keys.","Validate on the client before posting: ensure `email` is a non-empty string ≤ 320 chars.","If you added a new field, update `AuthPreflightBodySchema` rather than sending undeclared fields."],"exampleFix":"// before\nfetch('/api/auth/preflight', { method: 'POST', body: '{}' });\n\n// after\nfetch('/api/auth/preflight', {\n  method: 'POST',\n  headers: { 'content-type': 'application/json' },\n  body: JSON.stringify({ email: userInput.value }),\n});","handlingStrategy":"validation","validationCode":"import { z } from 'zod';\nconst Preflight = z.object({ email: z.string().min(1).max(320) }).strict();\nconst parsed = Preflight.safeParse(body);\nif (!parsed.success) throw new Error('email required');\nawait fetch('/api/auth/preflight', {\n  method: 'POST',\n  headers: { 'content-type': 'application/json' },\n  body: JSON.stringify(parsed.data),\n});","typeGuard":"function isPreflightBody(v: unknown): v is { email: string } {\n  return typeof v === 'object' && v !== null &&\n    typeof (v as any).email === 'string' && (v as any).email.length > 0 &&\n    (v as any).email.length <= 320;\n}","tryCatchPattern":null,"preventionTips":["Validate email client-side before posting to `/preflight`.","Match the server's strict schema exactly — no extra fields.","Return clear form errors when the email input is empty."],"tags":["validation","email","preflight","input"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}