title: 'Error: Cyclic dependency detected' occurs when I add unique identifier to my module
body: <p>I found what the problem is, when the problem occurs, but I don't uderstand why is it happening...</p>
  
  <p>This is my app.js, there is no problem over here, i tested it more than 10 times:</p>
  
  <pre><code>'use strict';
  const Joi = require('joi');
  Joi.objectId = require('joi-objectid')(Joi);
  const config = require('config');
  const mongoose = require('mongoose');
  const debug = require('debug')('app:api');
  const express = require('express');
  const path = require('path');
  const morgan = require('morgan');
  const bodyParser = require('body-parser');
  const { isNotFound, errorHandlerDev, errorHandlerPro } = require('./middleware/handlers');
  
  const index = require('./routes/index');
  const auth = require('./routes/auth');
  const users = require('./routes/users');
  
  const app = express();
  
  if(!config.get('jwtPrivateKey')) {
      console.log('KRİTİK HATA: JWT Private Key Tanımlanmadı!');
      process.exit(1);
  }
  if(!config.get('connectionString')) {
      console.log('KRİTİK HATA: Connection String Tanımlanmadı!');
      process.exit(1);
  }
  if(!process.env.USERNAME || !process.env.PASSWORD) {
      console.log('KRİTİK HATA: MongoDB Kullanıcı Bilgileri Eksik!');
      process.exit(1);
  }
  
  mongoose.connect(config.get('connectionString').replace(/({{USERNAME}}|{{PASSWORD}})/gi, match =&gt; { match = match.replace(/({|})/gi, symbol =&gt; ''); return process.env[match]; }))
      .then(() =&gt; debug('MongoDB &gt; Uptime-Monitor Başarıyla Bağlandı!'))
      .catch(error =&gt; debug('MongoDB &gt; Uptime-Monitor Bağlanırken Hata Oluştu! Hata Bilgisi:', error));
  
  app.use(morgan('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  
  app.use('/api/', index);
  app.use('/api/auth', auth);
  app.use('/api/users', users);
  
  app.use(isNotFound);
  
  if (app.get('env') === 'development') {
      app.use(errorHandlerDev);
  }
  
  app.use(errorHandlerPro);
  
  app.set('port', process.env.PORT || 5000);
  
  app.listen(app.get('port'), function () {
      debug(`Express Sunucusu Port ${app.get('port')} Üzerinde Çalışıyor!`);
  });
  </code></pre>
  
  <p>This is my User Model File, user.js:</p>
  
  <pre><code>'use strict';
  const config = require('config');
  const jwt = require('jsonwebtoken');
  const Joi = require('joi');
  Joi.objectId = require('joi-objectid')(Joi);
  const mongoose = require('mongoose');
  
  var model = {};
  
  // Required Data: username, email, phone, password
  // Optional Data: name, lastname, tosAgreement, isAdmin
  model.userSchema = new mongoose.Schema({
      name: {
          type: String,
          trim: true,
          minlength: [3, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
          maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.']
      },
      lastname: {
          type: String,
          trim: true,
          minlength: [3, 'Soyadınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
          maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.']
      },
      username: {
          type: String,
          trim: true,
          minlength: [3, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
          maxlength: [20, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
          //unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
          validate: {
              validator: function(v) {
                  let re = /^\w+$/;
                  return re.test(v);
              },
              message: 'Uygun Kullanıcı Adı Giriniz.'
          },
          match: [/^\w+$/, 'Uygun Kullanıcı Adı Giriniz.']
      },
      email: {
          type: String,
          trim: true,
          //unique: [true, 'İstenilen E-Posta Adresi Daha Önce Kullanılmış.'],
          lowercase: true,
          validate: {
              validator: function(v) {
                  let re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
                  return re.test(v);
              },
              message: 'Uygun E-Posta Adresi Giriniz.'
          },
          match: [/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 'Uygun E-Posta Adresi Giriniz.']
      },
      phone: {
          type: Number,
          required: [true, 'Telefon Numaranızı Girmeniz Gerekmektedir.'],
          //unique: [true, 'İstenilen Telefon Numarası Daha Önce Kullanılmış.'],
          min: [10, 'Telefon Numaranızın Uzunluğu Uygun Değildir. 10 Haneden Oluşmalıdır.'],
      },
      password: {
          type: String,
          trim: true,
          required: [true, 'Şifrenizi Girmeniz Gerekmektedir.'],
          minlength: 5,
          maxlength: 1024
      },
      registerDate: {
          type: Date,
          default: Date.now
      },
      tosAgreement: {
          type: Boolean,
          default: true
      },
      isAdmin: {
          type: Boolean,
          required: true,
          default: false
      }
  });
  
  model.userSchema.methods.generateToken = function() {
      return jwt.sign({ _id: this._id, isAdmin: this.isAdmin}, config.get('jwtPrivateKey'));
  };
  
  model.User = mongoose.model('User', model.userSchema);
  
  model.validate = user =&gt; {
      const Schema = {
          name: Joi.string().min(3).max(50),
          lastname: Joi.string().min(3).max(50),
          username: Joi.string().required().regex(/^\w+$/).min(3).max(20),
          email: Joi.string().required().min(3).email(),
          phone: Joi.number().required().min(10),
          password: Joi.string().required().min(5).max(255),
          tosAgreement: Joi.boolean().default(true),
          isAdmin: Joi.boolean().default(false)
      };
  
      return Joi.validate(user, Schema);
  };
  
  model.validateId = id =&gt; {
      return Joi.validate(id, Joi.objectId().required());
  };
  
  module.exports.model = model;
  </code></pre>
  
  <p>And lastly, my users.js, api/users router, there is no problem over here too:</p>
  
  <pre><code>'use strict';
  const auth = require('./../middleware/auth');
  const admin = require('./../middleware/admin');
  const bcyript = require('bcrypt');
  const _ = require('lodash');
  const mongoose = require('mongoose');
  const { userSchema, User, validate, validateId } = require('./../models/user');
  const express = require('express');
  const router = express.Router();
  
  router.get('/', [auth, admin], async (req, res) =&gt; {
      const users = await User.find().select({ _id: 1, name: 1, email: 1, tosAgreement: 1}).sort({ name: 1 });
      if(!users) return res.status(200).send({'BİLGİ': 'Hiç Kullanıcı Bulunamadı.'});
      res.status(200).send(users);
  });
  
  router.get('/me', auth, async (req, res) =&gt; {
      const user = await User.findById(req.user._id).select('-password -phone');
      res.status(200).send(user);
  });
  
  router.get('/:id', [auth, admin], async (req, res) =&gt; {
      const user = await User.findById(req.params.id).select({ _id: 1, name: 1, email: 1, tosAgreement: 1, isAdmin: true});
      if(!user) return res.status(404).send({'HATA': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
      res.status(200).send(user);
  });
  
  router.post('/', /*[auth, admin],*/async (req, res) =&gt; {
      const { error } = validate(req.body);
      if(error) return res.status(400).send({'Hata': error.details[0].message});
      let isAnyUserWithThatEmail = await User.findOne({ email: req.body.email });
      if(isAnyUserWithThatEmail) return res.status(400).send({'Hata': 'Belirtilen E-Posta Adresi Kullanımda.'});
      let isAnyUserWithThatPhone = await User.findOne({ phone: req.body.phone });
      if(isAnyUserWithThatPhone) return res.status(400).send({'Hata': 'Belirtilen Telefon Numarası Kullanımda.'});
      const user = new User(req.body);
      const salt = await bcyript.genSalt(10);
      user.password = await bcyript.hash(user.password, salt);
      await user.save();
      const token = user.generateToken();
      res.header('x-auth-token', token).status(201).send(_.pick(user, ['_id', 'name', 'email', 'tosAgreement', 'isAdmin']));
  });
  
  router.put('/:id', auth, async (req, res) =&gt; {
      const errorId = validateId(req.params.id).error;
      if(errorId) return res.status(400).json({'Hata': errorId.details[0].message});
      const { error } = validate(req.body);
      if(error) return res.status(400).send({'Hata': error.details[0].message});
      const salt = await bcyript.genSalt(10);
      const user = await User.findByIdAndUpdate(req.params.id, {
          name: req.body.name,
          lastname: req.body.lastname,
          email: req.body.email,
          phone: req.body.phone,
          password: await bcyript.hash(req.body.password, salt),
          tosAgreement: req.body.tosAgreement,
          isAdmin: req.body.isAdmin
      }, { new: true, runValidators: true });
      if(!user) return res.status(404).send({'Hata': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
      res.status(200).send(_.pick(user, ['_id', 'name', 'email', 'tosAgreement', 'isAdmin']));
  });
  
  router.delete('/:id', [auth, admin], async (req, res) =&gt; {
      const { error } = validateId(req.params.id);
      if(error) return res.status(400).json({'Hata': error.details[0].message});
      const user = await User.findByIdAndRemove(req.params.id);
      if(!user) return res.status(404).send({'Hata': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
      res.status(200).send(_.pick(user, ['_id', 'name', 'email', 'tosAgreement', 'isAdmin']));
  });
  
  module.exports = router;
  </code></pre>
  
  <p>The "Error: cyclic dependency detected." error occurs when I uncomment "unique: true" on my model (user.js). When I comment "unique: true" lines, it disapper. The problem is on here, but why? I need to use unique identifiers.</p>
  
  <pre><code>//@@@ NO ERROR WHEN COMMENT OUT THESE 'unique' IDENTIFIERS @@@
  ...
  username: {
      ...
      //unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
      ...
  },
  email: {
      ...
      //unique: [true, 'İstenilen E-Posta Adresi Daha Önce Kullanılmış.'],
      ...
  },
  phone: {
      ...
      //unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
      ...
  }
  ...
  </code></pre>