{"record":{"id":"cce3ec6a29b88222","repo":"n8n-io/n8n","slug":"invalid-request-cce3ec","errorCode":null,"errorMessage":"Invalid request","messagePattern":"Invalid request","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"packages/cli/src/controllers/auth.controller.ts","lineNumber":267,"sourceCode":"\n\t\tconst invitee = users.find((user) => user.id === inviteeId);\n\t\tif (!invitee || invitee.password) {\n\t\t\tthis.logger.error('Invalid invite URL - invitee already setup', {\n\t\t\t\tinviterId,\n\t\t\t\tinviteeId,\n\t\t\t});\n\t\t\tthrow new BadRequestError('The invitation was likely either deleted or already claimed');\n\t\t}\n\n\t\tconst inviter = users.find((user) => user.id === inviterId);\n\t\tif (!inviter?.email) {\n\t\t\tthis.logger.error(\n\t\t\t\t'Request to resolve signup token failed because inviter does not exist or is not set up',\n\t\t\t\t{\n\t\t\t\t\tinviterId: inviter?.id,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthrow new BadRequestError('Invalid request');\n\t\t}\n\n\t\tthis.eventService.emit('user-invite-email-click', { inviter, invitee });\n\n\t\tconst { firstName, lastName } = inviter;\n\t\treturn { inviter: { firstName, lastName } };\n\t}\n\n\t/** Log out a user */\n\t@Post('/logout')\n\tasync logout(req: AuthenticatedRequest, res: Response) {\n\t\tawait this.authService.invalidateToken(req);\n\t\tthis.authService.clearCookie(res);\n\t\treturn { loggedOut: true };\n\t}\n}\n","sourceCodeStart":249,"sourceCodeEnd":284,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controllers/auth.controller.ts#L249-L284","documentation":"BadRequestError (HTTP 400) 'Invalid request' thrown at auth.controller.ts:267 when the inviter row exists but has no `email`. The inviter is expected to be a fully set-up user (with email); a missing email means the inviter account is incomplete/broken, so the resolve refuses to expose inviter first/last name.","triggerScenarios":"An invitation was created by an inviter whose account was later reset or corrupted such that `email` is null/empty. Rare in normal flows since owners always have email; surfaces with direct DB tampering or partial migrations.","commonSituations":"DB migration/import that nullified inviter emails; manual SQL edits to the user table; an SSO/LDAP sync that wiped an email field after an invite was sent.","solutions":["Inspect the inviter row in the DB: `SELECT id,email FROM user WHERE id=<inviterId>` — if email is empty, repair the inviter's profile first.","Re-invite from a different, fully-set-up owner/admin account.","Re-run or fix the SSO/LDAP sync that dropped the email.","If the inviter no longer exists, re-create the invitation under a valid owner."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before resolving, ensure the inviter has an email set\nasync function inviterIsValid(u: { email?: string | null } | null) {\n  return !!u && !!u.email;\n}\n// gate resolve on inviterIsValid(await userRepo.findOneBy({ id: inviterId }))","typeGuard":"const inviterHasEmail = (u: unknown): u is { id: string; email: string } =>\n  typeof u === 'object' && u !== null && typeof (u as any).email === 'string' && (u as any).email.length > 0;","tryCatchPattern":"try {\n  await resolveSignupToken(token);\n} catch (e) {\n  if (e instanceof BadRequestError && e.message === 'Invalid request') {\n    // escalate to admin: inviter row is corrupted (no email)\n  }\n}","preventionTips":["Validate inviter rows have non-null email at the service boundary before issuing invites.","Run a periodic integrity check for owner/admin accounts missing required fields.","Prevent SSO/LDAP syncs from clearing required user fields like email."],"tags":["auth","invitation","bad-request","users"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}