Automattic/mongoose · error · CastError

Cast to Array failed for value "${value}" (type ${valueType}

Error message

Cast to Array failed for value "${value}" (type ${valueType}) at path "${path}"

What it means

Assigning a non-array value to an array path during a set/save (not a database load) throws CastError Array: mongoose will not guess how to coerce a scalar or arbitrary object into the array shape. Only init from the database or an enabled castNonArrays option allow scalar-to-[scalar] coercion.

Source

Thrown at lib/schema/array.js:424

        // 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);
};

/*!
 * ignore
 */

SchemaArray.prototype._castForPopulate = function _castForPopulate(value, doc) {
  // lazy load
  MongooseArray || (MongooseArray = require('../types').Array);

  if (Array.isArray(value)) {
    let i;
    const rawValue = value.__array ? value.__array : value;
    const len = rawValue.length;

    if (this.embeddedSchemaType && this.embeddedSchemaType.constructor !== Mixed) {
      try {
        for (i = 0; i < len; i++) {

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Assign an array: `doc.numbers = [5]`; split joined strings before assigning.
  2. Enable lenient coercion where acceptable: per-path `{ type: [String], castNonArrays: true }` or globally `mongoose.Schema.Types.Array.options.castNonArrays = true`.
  3. Normalize payload shapes at the API boundary so arrays stay arrays.

Example fix

// before
doc.tags = req.body.tags; // 'red,blue' -> CastError Array

// after
doc.tags = Array.isArray(req.body.tags)
  ? req.body.tags
  : String(req.body.tags).split(',').map(s => s.trim());
Defensive patterns

Strategy: validation

Validate before calling

const toArray = (v) =>
  Array.isArray(v) ? v
  : (v == null || v === '') ? []
  : String(v).split(',').map(s => s.trim());
doc.tags = toArray(req.body.tags);

Type guard

const isArrayInput = (v) => Array.isArray(v);

Prevention

When it happens

Trigger: `doc.numbers = 5` with `numbers: [Number]`; req.body delivering 'a,b,c' (a comma-joined string) where the schema wants [String]; an update $set writing an object onto an array of primitives.

Common situations: Form submissions and query strings producing joined strings; upstream APIs silently switching a field from array to scalar; forgetting split() before assignment.

Related errors


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