You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么保存Mongoose模型时提示user.save is not a function错误

错误成因排查
  • 核心原因:User.findOne() 是异步数据库操作方法,你没有添加await关键字等待查询完成,此时user变量实际存储的是Mongoose的Query查询对象,而非Mongoose文档实例,只有文档实例才携带save方法,Query对象没有该方法,调用就会抛出对应错误。
  • 次要排查点:如果添加await后仍报错,可检查如下场景:
    • 重置密码token无效或已过期,导致findOne查询结果为null,对null调用save方法也会触发该错误
    • 检查User模型的引入路径是否正确,是否成功引入了mongoose定义的模型实例
修复代码示例
// 给异步操作添加await,确保拿到查询返回的文档实例
let user = await User.findOne({
    resetPasswordToken: resetPasswordToken,
    resetPasswordExpire: { $gt: Date.now() },
});

// 增加空判断,避免查询结果为空时报错
if (!user) {
  return res.status(400).json({ errorMsg: "重置密码令牌无效或已过期" });
}

// 更新字段
user.password = req.body.password;
user.resetPasswordToken = undefined;
user.resetPasswordExpire = undefined;
// save操作也是异步,需要添加await等待执行完成
await user.save();
sendToken(user, 200, res);
额外注意点

你当前的用户Schema存在两处小问题,会影响功能稳定性:

  1. password字段的必填属性误写为requires,正确应为required,否则密码必填校验会不生效
  2. pre('save')钩子中如果没有修改密码调用next()后,没有终止后续代码执行,可能会重复哈希密码,建议调整为:
userSchema.pre("save", async function (next) {
  if (!this.isModified("password")) {
    return next();
  }
  this.password = await bcrypt.hash(this.password, 10);
  next();
});

内容的提问来源于stack exchange,提问作者Sefi R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:54:02