{"record":{"id":"152638baa640d0b3","repo":"n8n-io/n8n","slug":"token-is-required-152638","errorCode":null,"errorMessage":"Token is required","messagePattern":"Token is required","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"warning","filePath":"packages/cli/src/controllers/invitation.controller.ts","lineNumber":180,"sourceCode":"\t\tipRateLimit: { limit: 100, windowMs: 1 * Time.minutes.toMilliseconds },\n\t})\n\tasync acceptInvitationWithToken(\n\t\treq: AuthlessRequest,\n\t\tres: Response,\n\t\t@Body payload: AcceptInvitationRequestDto,\n\t) {\n\t\tif (isSsoCurrentAuthenticationMethod()) {\n\t\t\tthis.logger.debug(\n\t\t\t\t'Invite links are not supported on this system, please use single sign on instead.',\n\t\t\t);\n\t\t\tthrow new BadRequestError(\n\t\t\t\t'Invite links are not supported on this system, please use single sign on instead.',\n\t\t\t);\n\t\t}\n\n\t\tif (!payload.token) {\n\t\t\tthis.logger.debug('Request to accept invitation failed because token is missing');\n\t\t\tthrow new BadRequestError('Token is required');\n\t\t}\n\n\t\tconst { firstName, lastName, password } = payload;\n\n\t\t// Extract inviterId and inviteeId from JWT token\n\t\tconst { inviterId, inviteeId } = await this.userService.getInvitationIdsFromPayload(\n\t\t\tpayload.token,\n\t\t);\n\n\t\treturn await this.processInvitationAcceptance(\n\t\t\tinviterId,\n\t\t\tinviteeId,\n\t\t\tfirstName,\n\t\t\tlastName,\n\t\t\tpassword,\n\t\t\treq,\n\t\t\tres,\n\t\t);","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controllers/invitation.controller.ts#L162-L198","documentation":"A BadRequestError (HTTP 400) from acceptInvitationWithToken when payload.token is falsy. The acceptance flow needs a JWT token (carrying inviterId/inviteeId) to proceed; without it the request is rejected immediately after the SSO check. Logged at debug as 'token is missing'.","triggerScenarios":"POST to accept-invitation with a body whose token field is missing, empty, null, or undefined. Common with malformed clients, hand-crafted requests, or a frontend bug that strips the token from the URL before POSTing.","commonSituations":"Frontend reads the token from the query string but the link was truncated; the user manually navigated to the page without the token; a proxy/load balancer strips query params; client-side bug that fails to include token in the body.","solutions":["Ensure the invite URL contains the token query param and that the frontend forwards it verbatim in the POST body.","Validate the token is a non-empty string on the client before submitting.","Check that reverse proxies do not strip the token from the URL or body.","Re-request the invite link if the token was lost."],"exampleFix":"// before\nawait api.post('/accept-invitation', { firstName, lastName, password });\n\n// after\nif (!token) throw new Error('Invite token missing from URL');\nawait api.post('/accept-invitation', { token, firstName, lastName, password });","handlingStrategy":"validation","validationCode":"// Require a non-empty token string before POSTing.\nfunction readInviteTokenFromUrl(): string | null {\n  const t = new URLSearchParams(location.search).get('token');\n  return typeof t === 'string' && t.length > 0 ? t : null;\n}\nconst token = readInviteTokenFromUrl();\nif (!token) throw new Error('Invite token missing from URL');","typeGuard":"function isNonEmptyString(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  await api.post('/accept-invitation', { token, ...rest });\n} catch (e) {\n  if (e.response?.status === 400 && /token is required/i.test(e.response.data.message)) {\n    notify('Invite link is incomplete — request a new one.');\n    return;\n  }\n  throw e;\n}","preventionTips":["Forward the token query param verbatim into the POST body.","Validate the token is a non-empty string on the client.","Ensure reverse proxies do not strip query params from invite URLs."],"tags":["invitations","token","validation","rest-api"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}