n8n-io/n8n · error · NotFoundError

User not found

Error message

User not found

What it means

Returned by GET /users/:id/password-reset-link (scope user:resetPassword) when the user lookup yields no row. Note the lookup uses TypeORM findOneOrFail (which already throws EntityNotFoundError on miss), so this explicit if(!user) branch is effectively unreachable defense-in-depth; in practice you will see it only if findOneOrFail semantics change or the call is refactored to findOne.

Source

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

				};
			}),
		);

		return usersListSchema.parse({
			count,
			items: this.removeSupplementaryFields(publicUsers, listQueryOptions, req.user),
		});
	}

	@Get('/:id/password-reset-link')
	@GlobalScope('user:resetPassword')
	async getUserPasswordResetLink(req: UserRequest.PasswordResetLink) {
		const user = await this.userRepository.findOneOrFail({
			where: { id: req.params.id },
			relations: ['role'],
		});
		if (!user) {
			throw new NotFoundError('User not found');
		}

		if (
			req.user.role.slug === GLOBAL_ADMIN_ROLE.slug &&
			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;

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Confirm the target user id exists (GET /users/:id) before requesting the reset link.
  2. If the user was deleted, surface that to the admin rather than retrying the reset endpoint.
  3. Treat a 404 here as terminal — do not retry without changing the id.
Defensive patterns

Strategy: validation

Validate before calling

async function ensureUserExists(id: string) {
  const r = await fetch(`/rest/users/${id}`, { method: 'GET' });
  if (r.status === 404) throw new Error(`User ${id} does not exist; cannot request reset link`);
  if (!r.ok) throw new Error(`User lookup failed: ${r.status}`);
}
// await ensureUserExists(userId) before GET /users/:id/password-reset-link

Try / catch

try {
  await fetch(`/rest/users/${id}/password-reset-link`);
} catch (e) {
  if (e.statusCode === 404) { /* user is gone; do not retry */ }
  else throw e;
}

Prevention

When it happens

Trigger: Requesting a password reset link for an id that does not exist in the users table (deleted user, typo'd UUID, pending invite that has no user row yet), while authenticated as a user with the user:resetPassword global scope.

Common situations: Admin UI trying to reset a user that was hard-deleted between page load and click; copy-paste of an old user id; integration tests against a freshly migrated DB without seed users.

Related errors


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