jquense/yup · error · TypeError

`${name}` must be a Date or a value that can be `cast()` to

Error message

`${name}` must be a Date or a value that can be `cast()` to a Date

What it means

DateSchema's prepareParam (used by limit setters like min/max) accepts either a ref or a concrete value; if it is not a ref, it is cast via this.cast() and the result must pass _typeCheck as a valid Date. Values that cannot be cast to a Date (invalid strings, numbers out of range, arbitrary objects) throw this TypeError naming the parameter (`min` or `max`).

Source

Thrown at src/date.ts:70

        value = parseIsoDate(value);

        // 0 is a valid timestamp equivalent to 1970-01-01T00:00:00Z(unix epoch) or before.
        return !isNaN(value) ? new Date(value) : DateSchema.INVALID_DATE;
      });
    });
  }

  private prepareParam(
    ref: unknown | Ref<Date>,
    name: string,
  ): Date | Ref<Date> {
    let param: Date | Ref<Date>;

    if (!Ref.isRef(ref)) {
      let cast = this.cast(ref);
      if (!this._typeCheck(cast))
        throw new TypeError(
          `\`${name}\` must be a Date or a value that can be \`cast()\` to a Date`,
        );
      param = cast;
    } else {
      param = ref as Ref<Date>;
    }
    return param;
  }

  min(min: unknown | Ref<Date>, message = locale.min) {
    let limit = this.prepareParam(min, 'min');

    return this.test({
      message,
      name: 'min',
      exclusive: true,
      params: { min },
      skipAbsent: true,

View on GitHub (pinned to ff31eee8a2)

Solutions

  1. Pass a valid Date or ISO string: yup.date().min(new Date('2024-01-01')) or .min('2024-01-01T00:00:00Z').
  2. Pre-validate the value: isNaN(Date.parse(v)) check before passing it in.
  3. If using another date library, convert first: .min(dayjs(x).toDate()).

Example fix

// before
yup.date().min(config.minDate) // config.minDate = '01/2024'
// after
yup.date().min(new Date('2024-01-01T00:00:00Z'))
Defensive patterns

Strategy: validation

Validate before calling

const toLimit = (v) => {
  const d = v instanceof Date ? v : new Date(v);
  if (isNaN(d.getTime())) throw new TypeError(`invalid date limit: ${v}`);
  return d;
};
yup.date().min(toLimit(config.minDate));

Type guard

const isDateable = (v) => v instanceof Date || (typeof v === 'string' && !isNaN(Date.parse(v))) || typeof v === 'number';

Try / catch

try {
  schema = yup.date().min(rawLimit);
} catch (e) {
  if (e.message.includes('must be a Date or a value that can be')) {
    schema = yup.date().min(new Date()); // or surface a config error
  } else throw e;
}

Prevention

When it happens

Trigger: yup.date().min('not-a-date'), .max(someObject), .min(new Date('Invalid')) producing an invalid Date after cast, or a numeric timestamp string in an unexpected format that fails cast.

Common situations: Limits loaded from config/env/API as strings in non-ISO formats; passing a dayjs/moment object instead of a native Date or ISO string; timezone-dependent parse failures; new Date(undefined).

Related errors


AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31). Data as JSON: /api/errors/e800ec97cdc18844. Report an issue: GitHub.