Automattic/mongoose · error · CastError

Cast to string failed for value "${value}" at path "${path}"

Error message

Cast to string failed for value "${value}" at path "${path}"

What it means

The string caster accepts primitives and any object with a custom toString(), but refuses arrays and objects whose toString is still Object.prototype.toString -- '[object Object]' is not real data (gh-647, gh-3030). Values matching neither rule produce CastError('string', value, path).

Source

Thrown at lib/cast/string.js:36

  if (value == null) {
    return value;
  }

  // handle documents being passed
  if (typeof value?._id === 'string') {
    return value._id;
  }

  // Re: gh-647 and gh-3030, we're ok with casting using `toString()`
  // **unless** its the default Object.toString, because "[object Object]"
  // doesn't really qualify as useful data
  if (value.toString &&
      value.toString !== Object.prototype.toString &&
      !Array.isArray(value)) {
    return value.toString();
  }

  throw new CastError('string', value, path);
};

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Convert explicitly: doc.name = String(value), or value.join(', ') for arrays
  2. Pick the right property from the object: doc.name = obj.name
  3. Change the schema path to [String] if arrays of strings are the real payload

Example fix

// before
doc.code = ['US', 'NY']; // assigned to a String path

// after
doc.code = ['US', 'NY'].join('-'); // explicit conversion
Defensive patterns

Strategy: type-guard

Validate before calling

function toStringValue(v) {
  if (v == null) return v;
  if (Array.isArray(v)) return v.join(', ');
  if (typeof v === 'object') throw new TypeError('Expected a string, got object');
  return String(v);
}
doc.code = toStringValue(req.body.code);

Type guard

function isStringCastable(v) {
  if (v == null) return true;
  if (typeof v !== 'object') return true;
  return typeof v.toString === 'function' &&
    v.toString !== Object.prototype.toString;
}

Try / catch

try {
  await doc.save();
} catch (err) {
  if (err.name === 'CastError' && err.kind === 'string') {
    // err.value is the array/plain object; convert it explicitly and retry
  }
  throw err;
}

Prevention

When it happens

Trigger: doc.name = ['a', 'b']; doc.name = {}; nested objects from req.body assigned to a String path. Dates and other built-ins with custom toString() are fine; arrays never are.

Common situations: Multi-value form fields; JSON where a string field arrives as an object or array; subdocuments assigned to string paths; DTO fields typed as arrays upstream.

Related errors


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