{"record":{"id":"b43871fceb4cf9df","repo":"n8n-io/n8n","slug":"invalid-payload-or-url","errorCode":null,"errorMessage":"Invalid payload or URL","messagePattern":"Invalid payload or URL","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"warning","filePath":"packages/cli/src/controllers/invitation.controller.ts","lineNumber":117,"sourceCode":"\t\tlastName: string,\n\t\tpassword: string,\n\t\treq: AuthlessRequest,\n\t\tres: Response,\n\t): Promise<Awaited<ReturnType<UserService['toPublic']>>> {\n\t\tconst users = await this.userRepository.find({\n\t\t\twhere: [{ id: inviterId }, { id: inviteeId }],\n\t\t\trelations: ['role'],\n\t\t});\n\n\t\tif (users.length !== 2) {\n\t\t\tthis.logger.debug(\n\t\t\t\t'Request to fill out a user shell failed because the inviter ID and/or invitee ID were not found in database',\n\t\t\t\t{\n\t\t\t\t\tinviterId,\n\t\t\t\t\tinviteeId,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthrow new BadRequestError('Invalid payload or URL');\n\t\t}\n\n\t\tconst invitee = users.find((user) => user.id === inviteeId) as User;\n\n\t\tif (invitee.password) {\n\t\t\tthis.logger.debug(\n\t\t\t\t'Request to fill out a user shell failed because the invite had already been accepted',\n\t\t\t\t{ inviteeId },\n\t\t\t);\n\t\t\tthrow new BadRequestError('This invite has been accepted already');\n\t\t}\n\n\t\tinvitee.firstName = firstName;\n\t\tinvitee.lastName = lastName;\n\t\tinvitee.password = await this.passwordUtility.hash(password);\n\n\t\tconst updatedUser = await this.userRepository.save(invitee, { transaction: false });\n","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controllers/invitation.controller.ts#L99-L135","documentation":"A BadRequestError (HTTP 400) from the invitation-acceptance flow (processInvitationAcceptance). After loading the two users by inviterId and inviteeId, if fewer than 2 users are found the token is treated as invalid and the request is rejected. It signals that the invite link/token references users that do not exist in the DB — typically a tampered, expired, or already-consumed invite.","triggerScenarios":"POST to the acceptance endpoint with a token whose decoded inviterId or inviteeId no longer matches any user row — e.g. the invitee or inviter was deleted, the token was fabricated, or the DB was reset after the invite was sent.","commonSituations":"User clicks an old invite link after the inviter left and their account was deleted; DB restore/rollback that dropped user rows; token forgery; invite generated on a different instance (wrong DB).","solutions":["Request a fresh invite from an admin; the old token's referenced users no longer exist.","Ensure the invitee/inviter user rows still exist in the user table (Admin UI > Users).","Confirm the instance URL matches the one that issued the invite (tokens are instance-specific).","Regenerate the invite and use the new link promptly."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Tokens are opaque JWTs; you cannot fully validate client-side, but sanity-check structure.\nfunction looksLikeInviteToken(t: unknown): boolean {\n  return typeof t === 'string' && t.split('.').length === 3;\n}\nif (!looksLikeInviteToken(token)) throw new Error('Malformed invite token');","typeGuard":null,"tryCatchPattern":"try {\n  await api.post('/accept-invitation', { token, firstName, lastName, password });\n} catch (e) {\n  if (e.response?.status === 400 && /Invalid payload or URL/i.test(e.response.data.message)) {\n    notify('This invite is no longer valid — request a new one.');\n    return;\n  }\n  throw e;\n}","preventionTips":["Treat invite tokens as single-use and short-lived; re-issue when in doubt.","Do not delete the inviter/invitee user rows while invites are outstanding.","Ensure the instance URL matches the one that issued the invite."],"tags":["invitations","token","rest-api","data-integrity"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}