I am getting an error "Error: User validation failed" in MongoDB

Issue

I am getting an error after trying to use the POST method through postman to register a user. I have created a simple Schema for the register route.

Error:

Error in register: Error: User validation failed: password: Cast to string failed for value "Promise { <pending> }" (type Promise) at path "password"
    at ValidationError.inspect (/Users/*****/authSystem/node_modules/mongoose/lib/error/validation.js:48:26)
    at formatValue (node:internal/util/inspect:782:19)
    at inspect (node:internal/util/inspect:347:10)
    at formatWithOptionsInternal (node:internal/util/inspect:2167:40)
    at formatWithOptions (node:internal/util/inspect:2029:10)
    at console.value (node:internal/console/constructor:324:14)
    at console.log (node:internal/console/constructor:360:61)
    at /Users/harshmishra/Desktop/BackendApp/authSystem/app.js:46:17
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {

  errors: {
    password: CastError: Cast to string failed for value "Promise { <pending> }" (type Promise) at path "password"
        at SchemaString.cast (/Users/*****/authSystem/node_modules/mongoose/lib/schema/string.js:600:11)
        at SchemaString.SchemaType.applySetters (/Users/*****/authSystem/node_modules/mongoose/lib/schematype.js:1189:12)
        at model.$set (/Users/***/authSystem/node_modules/mongoose/lib/document.js:1409:20)
        at model.$set (/Users/*****/authSystem/node_modules/mongoose/lib/document.js:1137:16)
        at model.Document (/Users/****/authSystem/node_modules/mongoose/lib/document.js:162:12)
        at model.Model (/Users/****/authSystem/node_modules/mongoose/lib/model.js:115:12)
        at new model (/Users/*****/authSystem/node_modules/mongoose/lib/model.js:4825:15)
        at /Users*****/authSystem/node_modules/mongoose/lib/model.js:3132:22
        at /Users/*****/authSystem/node_modules/mongoose/lib/model.js:3168:7
        at Array.forEach (<anonymous>) {
      stringValue: '"Promise { <pending> }"',
      messageFormat: undefined,
      kind: 'string',
      value: [Promise],
      path: 'password',
      reason: null,
      valueType: 'Promise'
    }
  },
  _message: 'User validation failed'
}

Schema:

const userSchema = new mongoose.Schema(
  {
    firstName: {
      type: String,
      default: null,
    },
    lastName: {
      type: String,
      default: null,
    },
    email: {
      type: String,
      unique: true,
    },
    password: {
      type: String,
    },
    token: {
      type: String,
    },
  },
);

module.exports = mongoose.model('User', userSchema)

/register:

app.post("/register", async(req, res) => {
    try {
        const { firstName, lastName, email, password } = req.body;
        if (!(firstName && lastName && email && password)) {
         return res.status(400).send("All fields are required");
        }
        const existingUser =User.findOne({ email });

        if (existingUser) {
          return res.status(401).send("User already exist");
        }
        const myEncrpytedPass = await bcryptjs.hash(password, 10);
        const user = await User.create({
          firstName,
          lastName,
          email: email.toLowerCase(),
          password: myEncrpytedPass,
        });
        const token = await jwt.sign(
          {
            user_id: user._id,
            email,
          },
          process.env.SECRET_KEY,
          {
            expiresIn: "4h",
          }
        );
        user.token = token;
      return res.status(201).json(user);
    } catch (error) {
        console.log("Error in register:",error)
   }
})

I am not able to figure out what I am doing wrong here? As I have followed the docs of a mongoose but still I am getting the error.

What changes should I make here?

Solution

There are two things that you need to change:

First

Try adding await before the bcryptjs.hash(). Looks like that function returns a Promise.

const myEncrpytedPass = await bcryptjs.hash(password, 10);

Second

Add return before each res.send.

For example, if user exists, you will send this res.send(401).send("User already exist"), but because you didn’t add return, function will continue, and will reach to the next res.status(201).json(user) response. This will throw an error like Cannot set headers after they are sent to the client because you have already sent the response to the user.

Answered By – NeNaD

Answer Checked By – Cary Denson (AngularFixing Admin)

Leave a Reply

Your email address will not be published.