n8n-io/n8n · error · NotFoundError

User to generate invite link for not found

Error message

User to generate invite link for not found

What it means

Thrown by POST /users/:id/invite-link (scope user:generateInviteLink) when userRepository.findOne({where:{id:inviteeId}}) returns null — i.e. no user exists for the path id. Unlike findOneOrFail, this is a plain findOne so the explicit null check is the only guard; HTTP 404.

Source

Thrown at packages/cli/src/controllers/users.controller.ts:182

			user.role.slug === GLOBAL_OWNER_ROLE.slug
		) {
			throw new ForbiddenError('Admin cannot reset password of global owner');
		}

		const link = this.authService.generatePasswordResetUrl(user);
		return { link };
	}

	@Post('/:id/invite-link')
	@GlobalScope('user:generateInviteLink')
	async generateInviteLink(req: AuthenticatedRequest<{ id: string }, {}, {}, {}>, _res: Response) {
		const inviterId = req.user.id;
		const inviteeId = req.params.id;

		const targetUser = await this.userRepository.findOne({ where: { id: inviteeId } });

		if (!targetUser) {
			throw new NotFoundError('User to generate invite link for not found');
		}

		const token = this.jwtService.sign(
			{
				inviterId,
				inviteeId,
			},
			{
				expiresIn: '90d',
			},
		);

		const baseUrl = this.urlService.getInstanceBaseUrl();
		const inviteLink = `${baseUrl}/signup?token=${token}`;

		return { link: inviteLink };
	}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Verify the invitee id via GET /users/:id before requesting an invite link.
  2. If the invitee was deleted, recreate the user/invite rather than regenerating the link.
  3. Do not retry the same id; treat 404 as terminal.
Defensive patterns

Strategy: validation

Validate before calling

async function ensureInviteeExists(id: string) {
  const r = await fetch(`/rest/users/${id}`);
  if (r.status === 404) throw new Error(`Invitee ${id} not found; recreate the invite instead`);
}
// call before POST /users/:id/invite-link

Try / catch

try { await fetch(`/rest/users/${id}/invite-link`, { method: 'POST' }); }
catch (e) { if (e.statusCode === 404) { /* recreate invite */ } else throw e; }

Prevention

When it happens

Trigger: POST /users/<unknown-id>/invite-link where <unknown-id> is not present in the users table (typo, deleted invitee, invitee id from a different environment).

Common situations: Re-triggering an invite-link generation for an invitee whose row was purged by the cleanup job; cross-environment id copy; UI caching a stale user list.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/b5ff84875955c1dc. Report an issue: GitHub.