{"record":{"id":"d426f038d4b96d79","repo":"Automattic/mongoose","slug":"cast-to-e-kind-failed-for-value-value-t","errorCode":null,"errorMessage":"Cast to [${e.kind}] failed for value \"${value}\" (type ${valueType}) at path \"${path}.${i}\"","messagePattern":"Cast to \\[(.+?)\\] failed for value \"(.+?)\" \\(type (.+?)\\) at path \"(.+?)\\.(.+?)\"","errorType":"exception","errorClass":"CastError","httpStatus":null,"severity":"error","filePath":"lib/schema/array.js","lineNumber":407,"sourceCode":"          // skip if possible.\n          if (isMongooseArray) {\n            if (options.arrayPath != null) {\n              opts.arrayPathIndex = i;\n            } else if (caster._arrayParentPath != null) {\n              opts.arrayPathIndex = i;\n            }\n          }\n          if (options.hydratedPopulatedDocs) {\n            opts.hydratedPopulatedDocs = options.hydratedPopulatedDocs;\n          }\n          if (options.virtuals) {\n            opts.virtuals = options.virtuals;\n          }\n          rawValue[i] = caster.applySetters(rawValue[i], doc, init, void 0, opts);\n        }\n      } catch (e) {\n        // rethrow\n        throw new CastError('[' + e.kind + ']', util.inspect(value), this.path + '.' + i, e, this);\n      }\n    }\n\n    return value;\n  }\n\n  const castNonArraysOption = this.options.castNonArrays ?? SchemaArray.options.castNonArrays;\n  if (init || castNonArraysOption) {\n    // gh-2442: if we're loading this from the db and its not an array, mark\n    // the whole array as modified.\n    if (doc && init) {\n      doc.markModified(this.path);\n    }\n    return this.cast([value], doc, init);\n  }\n\n  throw new CastError('Array', util.inspect(value), this.path, null, this);\n};","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/schema/array.js#L389-L425","documentation":"While casting each element of an array assigned to a document (set/save), the embedded schema type's caster threw; mongoose rewraps it as a CastError with the embedded kind in brackets, the whole value, and the failing index appended to the path (path.i). The [Kind], value, and index pinpoint the bad element.","triggerScenarios":"`doc.tags = ['ok', 'xyz']` with `tags: [Number]`; assigning strings that are not 24-hex to a `[ObjectId]` path; `[Date]` with element '32/13/2020'; nested arrays where an inner element fails to cast.","commonSituations":"Unvalidated request bodies (strings from forms/JSON) written straight to typed arrays; upstream APIs changing element types; mixed-quality imported data.","solutions":["Fix or filter the element at the reported index - path.i names it exactly.","Validate arrays at the API boundary (zod/joi) before assignment, or enable runValidators on the assignment path.","Only if intentional, loosen the failing element type (e.g. store as [Mixed]) rather than weakening the whole path."],"exampleFix":"// before\ndoc.ids = req.body.ids; // ['507f1f77bcf86cd799439011', 'not-an-id'] -> CastError [ObjectId] at ids.1\n\n// after\nconst ok = req.body.ids.every(v => /^[0-9a-fA-F]{24}$/.test(v));\nif (!ok) return res.status(400).json({ error: 'invalid ids' });\ndoc.ids = req.body.ids;","handlingStrategy":"try-catch","validationCode":"const isValidObjectId = (v) => v == null || /^[0-9a-fA-F]{24}$/.test(v) || v instanceof mongoose.Types.ObjectId;\nconst allElementsCastable = (arr) => Array.isArray(arr) && arr.every(isValidObjectId);\nif (!allElementsCastable(req.body.ids)) return res.status(400).json({ error: 'bad ids' });\ndoc.ids = req.body.ids;","typeGuard":null,"tryCatchPattern":"try {\n  doc.arr = input;\n  await doc.save();\n} catch (err) {\n  if (err instanceof mongoose.Error.CastError && err.path?.startsWith('arr.')) {\n    // err.path names the failing element (e.g. arr.1), err.value the bad input\n    return res.status(400).json({ error: `invalid value at ${err.path}` });\n  }\n  throw err;\n}","preventionTips":["Map request payloads through runtime validation (zod/joi) so cast errors never reach mongoose.","Log err.path and err.value from CastError - they pinpoint the failing index immediately.","For ObjectId arrays, pre-check 24-hex format before assignment."],"tags":["cast-error","arrays","input-validation","save"],"backgroundTag":"mongoose-cast-error","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}