angular/components · error

Formats array must not be empty.

Error message

Formats array must not be empty.

What it means

The date-fns adapter's _parse method requires at least one parse format so it can attempt to interpret the user's input string as a date. The code builds a formats array from parseFormat, but the guard checks `!parseFormat.length` on the original input — so it throws when the input is an empty array (or when a string is passed, since strings also have `.length`... practically, an empty array input). Without any format the subsequent parse loop would do nothing and return null, so the library fails fast with this error instead.

Source

Thrown at src/material-date-fns-adapter/adapter/date-fns-adapter.ts:275

  private _parse(
    value: unknown,
    parseFormat: string | string[],
    shouldTryParseIso = true,
  ): Date | null {
    if (typeof value == 'string' && value.length > 0) {
      if (shouldTryParseIso) {
        const iso8601Date = parseISO(value);

        if (this.isValid(iso8601Date)) {
          return iso8601Date;
        }
      }

      const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat];

      if (!parseFormat.length) {
        throw Error('Formats array must not be empty.');
      }

      for (const currentFormat of formats) {
        const fromFormat = parse(value, currentFormat, new Date(), {locale: this.locale});

        if (this.isValid(fromFormat)) {
          return fromFormat;
        }
      }

      return this.invalid();
    } else if (typeof value === 'number') {
      return new Date(value);
    } else if (value instanceof Date) {
      return this.clone(value);
    }

    return null;

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Ensure the array passed to parse contains at least one format string, e.g. `formats.length ? formats : ['yyyy-MM-dd']`.
  2. Check your MAT_DATE_FORMATS parse.dateInput configuration — it must be a non-empty string or non-empty array.
  3. If formats are computed dynamically, add a fallback default before calling parse.
  4. Wrap the call in try/catch if input formats are user-supplied and cannot be pre-validated.

Example fix

// before
adapter.parse('2024-01-15', []);

// after
adapter.parse('2024-01-15', ['yyyy-MM-dd']);
// or guard:
const formats = userFormats.length ? userFormats : ['yyyy-MM-dd'];
adapter.parse('2024-01-15', formats);
Defensive patterns

Strategy: validation

Validate before calling

const formats: string | string[] = getConfiguredParseFormats();
const list = Array.isArray(formats) ? formats : [formats];
if (!list.length) throw new Error('parse requires at least one format');
adapter.parse(value, list);

Type guard

function hasFormats(f: string | string[]): f is string | [string, ...string[]] {
  return typeof f === 'string' ? f.length > 0 : f.length > 0;
}

Try / catch

try {
  return adapter.parse(value, formats);
} catch (e) {
  if (e.message.includes('Formats array must not be empty')) return null;
  throw e;
}

Prevention

When it happens

Trigger: Calling `adapter.parse(value, [])` (empty array of formats), or indirectly from parseTime with an empty format array. Note the guard checks the raw input, so a non-empty string/array passes but an empty array throws.

Common situations: Passing a dateFormats config array that is built dynamically (e.g. filtered from user or locale settings) and ends up empty; passing `[]` as the MAT_DATE_FORMATS parse.dateInput; wiring parseTime with an empty formats list.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/b5514285c953c416. Report an issue: GitHub.