{"record":{"id":"3c292ccbccbaea30","repo":"Automattic/mongoose","slug":"cast-to-string-failed-for-value-value-type-3c292c","errorCode":null,"errorMessage":"Cast to string failed for value \"${value}\" (type ${valueType}) at path \"${path}\"","messagePattern":"Cast to string failed for value \"(.+?)\" \\(type (.+?)\\) at path \"(.+?)\"","errorType":"validation","errorClass":"CastError","httpStatus":null,"severity":"error","filePath":"lib/schema/string.js","lineNumber":610,"sourceCode":"\nSchemaString.prototype.cast = function(value, doc, init, prev, options) {\n  if (typeof value !== 'string' && SchemaType._isRef(this, value, doc, init)) {\n    return this._castRef(value, doc, init, options);\n  }\n\n  let castString;\n  if (typeof this._castFunction === 'function') {\n    castString = this._castFunction;\n  } else if (typeof this.constructor.cast === 'function') {\n    castString = this.constructor.cast();\n  } else {\n    castString = SchemaString.cast();\n  }\n\n  try {\n    return castString(value);\n  } catch {\n    throw new CastError('string', value, this.path, null, this);\n  }\n};\n\n/*!\n * ignore\n */\n\nfunction handleSingle(val, context) {\n  return this.castForQuery(null, val, context);\n}\n\n/*!\n * ignore\n */\n\nfunction handleArray(val, context) {\n  const _this = this;\n  if (!Array.isArray(val)) {","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/schema/string.js#L592-L628","documentation":"CastError thrown when mongoose's string caster cannot convert a value for a String path. The built-in caster (lib/cast/string.js) accepts null/undefined, strings, numbers, booleans, dates, ObjectIds, documents with a string `_id`, and objects with a custom `toString()`; it rejects plain objects (default Object.prototype.toString would give '[object Object]'), arrays, and objects without toString.","triggerScenarios":"`doc.name = {}` or `doc.name = ['a']`; `Model.find({ name: req.query.name })` when an Express extended query like `?name[a]=b` parses to an object; spreading API payloads that contain nested objects into a flat string field.","commonSituations":"Express qs parser producing arrays/objects from repeated or bracketed params; JSON payloads where a field is sometimes an object; changing a path from Mixed/Object to String while legacy data still has objects.","solutions":["Normalize the value to a string before assigning (`v == null ? v : String(v)`), keeping in mind `String({})` yields '[object Object]'","If structured data is legitimate, change the path type to Schema.Types.Mixed or a subdocument schema","Sanitize request params (flattening objects/arrays) before they reach the model","Install a global custom caster via `mongoose.Schema.Types.String.cast(fn)` only if you own the coercion rules"],"exampleFix":"// before\nconst doc = new Model({ name: req.body.name }); // req.body.name === { first: 'A' }\n\n// after\nconst raw = req.body.name;\nconst doc = new Model({ name: typeof raw === 'object' && raw !== null ? JSON.stringify(raw) : raw });\n// or declare the path as Schema.Types.Mixed if objects are intended","handlingStrategy":"validation","validationCode":"function isStringable(v) {\n  if (v == null) return true;\n  if (typeof v !== 'object') return true; // string, number, boolean, symbol cast via toString\n  if (Array.isArray(v)) return false;\n  if (typeof v.toString === 'function' && v.toString !== Object.prototype.toString) return true;\n  return false;\n}\n// before assigning or querying:\nif (!isStringable(value)) throw new TypeError(`field 'name' expects a string, got ${typeof value}`);","typeGuard":"const isStringable = v => v == null || typeof v !== 'object' || (!Array.isArray(v) && typeof v.toString === 'function' && v.toString !== Object.prototype.toString);","tryCatchPattern":"try {\n  doc.name = value;\n} catch (err) {\n  if (err instanceof mongoose.Error.CastError && err.kind === 'string') {\n    // handle bad input: log err.path, err.value and reject the payload\n  } else throw err;\n}","preventionTips":["Treat CastError with kind 'string' as input rejection, not a crash; map it to a 400 response","Flatten/serialize objects before they reach string paths","Watch Express extended query parsing (?a[b]=c produces objects) on string filters"],"tags":["mongoose","cast","string","schema","query"],"backgroundTag":"value-cast-failed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}