Automattic/mongoose · error · CastError

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

Error message

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

What it means

SchemaDate.cast wraps the date caster (lib/cast/date.js) and converts any failure into a CastError of type 'date'. The caster accepts Date instances (rejected if Invalid Date), numbers and numeric millisecond strings, moment-like objects via valueOf(), and any string the Date constructor can parse; it explicitly rejects booleans and everything that yields NaN. null/undefined and empty string pass through as null.

Source

Thrown at lib/schema/date.js:380

 *
 * @param {object} value to cast
 * @api private
 */

SchemaDate.prototype.cast = function(value) {
  let castDate;
  if (typeof this._castFunction === 'function') {
    castDate = this._castFunction;
  } else if (typeof this.constructor.cast === 'function') {
    castDate = this.constructor.cast();
  } else {
    castDate = SchemaDate.cast();
  }

  try {
    return castDate(value);
  } catch (error) {
    throw new CastError('date', value, this.path, error, this);
  }
};

/**
 * Date Query casting.
 *
 * @param {any} val
 * @api private
 */

function handleSingle(val) {
  return this.cast(val);
}

const $conditionalHandlers = {
  ...SchemaType.prototype.$conditionalHandlers,
  $gt: handleSingle,
  $gte: handleSingle,

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Normalize input before assigning: `const d = new Date(input); if (Number.isNaN(d.getTime())) throw ...`
  2. Use a proper date parser (dayjs/moment with a format string) for locale-specific strings, then assign `.toDate()`
  3. Register a global custom caster with `mongoose.Schema.Types.Date.cast(v => ...)` that accepts your formats and throws on garbage
  4. Reject boolean/truthy values at the request-validation boundary

Example fix

// before
user.dob = req.body.dob; // '05/03/2024' or free text

// after
const dob = dayjs(req.body.dob, 'DD/MM/YYYY').toDate();
if (Number.isNaN(dob.getTime())) throw new ValidationError('bad dob');
user.dob = dob;
Defensive patterns

Strategy: validation

Validate before calling

function toSafeDate(v) {
  if (v == null || v === '') return null;
  if (v instanceof Date) { if (Number.isNaN(v.getTime())) throw new Error('invalid Date'); return v; }
  if (typeof v === 'boolean') throw new Error('boolean is not a date');
  const d = new Date(typeof v.valueOf === 'function' ? v.valueOf() : v);
  if (Number.isNaN(d.getTime())) throw new Error(`unparseable date: ${v}`);
  return d;
}

Type guard

function isDateLike(v) {
  return v == null || v === '' || v instanceof Date || typeof v === 'number' ||
    (typeof v === 'string' && !Number.isNaN(new Date(v).getTime()));
}

Try / catch

try { doc.when = value; } catch (err) { if (err.name === 'CastError' && err.kind === 'date') { return badRequest(`invalid date for ${err.path}`); } throw err; }

Prevention

When it happens

Trigger: `doc.createdAt = 'yesterday'` (unparseable string), `doc.d = true` (booleans asserted against), `doc.d = new Date('nope')` (Invalid Date instance), a moment-like object whose valueOf() returns NaN, or a string like '12/34/2024' whose Date parse yields NaN. Also `Model.find({ createdAt: { $gt: 'gibberish' } })` via handleSingle.

Common situations: Free-text form inputs mapped straight onto Date paths; locale-formatted dates ('31/02/2024', 'dd.mm.yyyy') that Date.parse cannot handle; third-party APIs returning non-ISO date strings; booleans leaking in from truthy/falsy flag logic.

Related errors


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