Automattic/mongoose · error · CastError

Cast to [${e.kind}] failed for value "${value}" (type ${valu

Error message

Cast to [${e.kind}] failed for value "${value}" (type ${valueType}) at path "${path}.${i}"

What it means

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.

Source

Thrown at lib/schema/array.js:407

          // skip if possible.
          if (isMongooseArray) {
            if (options.arrayPath != null) {
              opts.arrayPathIndex = i;
            } else if (caster._arrayParentPath != null) {
              opts.arrayPathIndex = i;
            }
          }
          if (options.hydratedPopulatedDocs) {
            opts.hydratedPopulatedDocs = options.hydratedPopulatedDocs;
          }
          if (options.virtuals) {
            opts.virtuals = options.virtuals;
          }
          rawValue[i] = caster.applySetters(rawValue[i], doc, init, void 0, opts);
        }
      } catch (e) {
        // rethrow
        throw new CastError('[' + e.kind + ']', util.inspect(value), this.path + '.' + i, e, this);
      }
    }

    return value;
  }

  const castNonArraysOption = this.options.castNonArrays ?? SchemaArray.options.castNonArrays;
  if (init || castNonArraysOption) {
    // gh-2442: if we're loading this from the db and its not an array, mark
    // the whole array as modified.
    if (doc && init) {
      doc.markModified(this.path);
    }
    return this.cast([value], doc, init);
  }

  throw new CastError('Array', util.inspect(value), this.path, null, this);
};

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Fix or filter the element at the reported index - path.i names it exactly.
  2. Validate arrays at the API boundary (zod/joi) before assignment, or enable runValidators on the assignment path.
  3. Only if intentional, loosen the failing element type (e.g. store as [Mixed]) rather than weakening the whole path.

Example fix

// before
doc.ids = req.body.ids; // ['507f1f77bcf86cd799439011', 'not-an-id'] -> CastError [ObjectId] at ids.1

// after
const ok = req.body.ids.every(v => /^[0-9a-fA-F]{24}$/.test(v));
if (!ok) return res.status(400).json({ error: 'invalid ids' });
doc.ids = req.body.ids;
Defensive patterns

Strategy: try-catch

Validate before calling

const isValidObjectId = (v) => v == null || /^[0-9a-fA-F]{24}$/.test(v) || v instanceof mongoose.Types.ObjectId;
const allElementsCastable = (arr) => Array.isArray(arr) && arr.every(isValidObjectId);
if (!allElementsCastable(req.body.ids)) return res.status(400).json({ error: 'bad ids' });
doc.ids = req.body.ids;

Try / catch

try {
  doc.arr = input;
  await doc.save();
} catch (err) {
  if (err instanceof mongoose.Error.CastError && err.path?.startsWith('arr.')) {
    // err.path names the failing element (e.g. arr.1), err.value the bad input
    return res.status(400).json({ error: `invalid value at ${err.path}` });
  }
  throw err;
}

Prevention

When it happens

Trigger: `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.

Common situations: Unvalidated request bodies (strings from forms/JSON) written straight to typed arrays; upstream APIs changing element types; mixed-quality imported data.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/d426f038d4b96d79. Report an issue: GitHub.