{"record":{"id":"a3d63fe0a6ffeeb0","repo":"Automattic/mongoose","slug":"cast-to-this-instance-failed-for-value-value","errorCode":null,"errorMessage":"Cast to ${this.instance} failed for value \"${value}\" (type ${valueType}) at path \"${this.path}\"","messagePattern":"Cast to (.+?) failed for value \"(.+?)\" \\(type (.+?)\\) at path \"(.+?)\"","errorType":"validation","errorClass":"CastError","httpStatus":null,"severity":"error","filePath":"lib/schemaType.js","lineNumber":1713,"sourceCode":" * ignore\n */\n\nSchemaType.prototype._castRef = function _castRef(value, doc, init, options) {\n  if (value == null) {\n    return value;\n  }\n\n  if (value.$__ != null) {\n    value.$__.wasPopulated = value.$__.wasPopulated || { value: value._doc._id };\n    return value;\n  }\n\n  // setting a populated path\n  if (Buffer.isBuffer(value) || !utils.isObject(value)) {\n    if (init) {\n      return value;\n    }\n    throw new CastError(this.instance, value, this.path, null, this);\n  }\n\n  // Handle the case where user directly sets a populated\n  // path to a plain object; cast to the Model used in\n  // the population query.\n  const path = doc.$__fullPath(this.path, true);\n  const owner = doc.ownerDocument();\n  const pop = owner.$populated(path, true);\n\n  let ret = value;\n  if (!doc.$__.populated ||\n    !doc.$__.populated[path] ||\n    !doc.$__.populated[path].options ||\n    !doc.$__.populated[path].options.options ||\n    !doc.$__.populated[path].options.options.lean) {\n    const PopulatedModel = pop ? pop.options[populateModelSymbol] : owner.constructor.db.model(this.options.ref);\n    ret = PopulatedModel.hydrate(value, null, options);\n    ret.$__.wasPopulated = { value: ret._doc._id, options: { [populateModelSymbol]: PopulatedModel } };","sourceCodeStart":1695,"sourceCodeEnd":1731,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/schemaType.js#L1695-L1731","documentation":"CastError thrown from SchemaType.prototype.cast() when a path that is currently populated is assigned a non-object value (a primitive, string, number, or Buffer). A populated path must hold a document of the populated model, so scalars cannot be cast; without populate the same value (e.g. an ObjectId string) would cast fine.","triggerScenarios":"doc.populate('owner').then(() => { doc.owner = '64b1...'; }) — assigning a raw id string to a populated ref path; doc.set('owner', 5) or assigning a Buffer while the path is populated.","commonSituations":"Trying to reset a populated reference back to an _id after populate; assigning values parsed from JSON/web requests onto populated documents; spreading request bodies onto populated docs.","solutions":["Assign an object with the _id: doc.owner = { _id: ownerId }","Or depopulate first, then set the scalar: doc.depopulate('owner'); doc.owner = ownerId;","Or assign a real model instance: doc.owner = await User.findById(ownerId)"],"exampleFix":"// before\nawait doc.populate('owner');\ndoc.owner = '64b1f0c2e4b0a1d2c3e4f5a6'; // CastError\n// after\nawait doc.populate('owner');\ndoc.owner = { _id: '64b1f0c2e4b0a1d2c3e4f5a6' };","handlingStrategy":"try-catch","validationCode":"function setRef(doc, path, value) {\n  if (doc.$populated && doc.$populated(path) && (typeof value !== 'object' || value === null || Buffer.isBuffer(value))) {\n    doc.depopulate(path);\n  }\n  doc.set(path, value);\n}","typeGuard":"function isPopulatedDocValue(value) {\n  return value != null && typeof value === 'object' && !Buffer.isBuffer(value);\n}","tryCatchPattern":"try { doc.owner = rawId; } catch (err) { if (err.name === 'CastError' && err.path === 'owner') { doc.owner = { _id: rawId }; } else throw err; }","preventionTips":["After populate, treat ref paths as holding documents — assign objects or model instances","Centralize ref assignment in a setter that depopulates first when a scalar arrives","Watch for request-body spreads onto populated docs in integration tests"],"tags":["mongoose","populate","cast-error","reference"],"backgroundTag":"type-cast-failed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}