{"record":{"id":"b5514285c953c416","repo":"angular/components","slug":"formats-array-must-not-be-empty","errorCode":null,"errorMessage":"Formats array must not be empty.","messagePattern":"Formats array must not be empty\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material-date-fns-adapter/adapter/date-fns-adapter.ts","lineNumber":275,"sourceCode":"\n  private _parse(\n    value: unknown,\n    parseFormat: string | string[],\n    shouldTryParseIso = true,\n  ): Date | null {\n    if (typeof value == 'string' && value.length > 0) {\n      if (shouldTryParseIso) {\n        const iso8601Date = parseISO(value);\n\n        if (this.isValid(iso8601Date)) {\n          return iso8601Date;\n        }\n      }\n\n      const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat];\n\n      if (!parseFormat.length) {\n        throw Error('Formats array must not be empty.');\n      }\n\n      for (const currentFormat of formats) {\n        const fromFormat = parse(value, currentFormat, new Date(), {locale: this.locale});\n\n        if (this.isValid(fromFormat)) {\n          return fromFormat;\n        }\n      }\n\n      return this.invalid();\n    } else if (typeof value === 'number') {\n      return new Date(value);\n    } else if (value instanceof Date) {\n      return this.clone(value);\n    }\n\n    return null;","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material-date-fns-adapter/adapter/date-fns-adapter.ts#L257-L293","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the array passed to parse contains at least one format string, e.g. `formats.length ? formats : ['yyyy-MM-dd']`.","Check your MAT_DATE_FORMATS parse.dateInput configuration — it must be a non-empty string or non-empty array.","If formats are computed dynamically, add a fallback default before calling parse.","Wrap the call in try/catch if input formats are user-supplied and cannot be pre-validated."],"exampleFix":"// before\nadapter.parse('2024-01-15', []);\n\n// after\nadapter.parse('2024-01-15', ['yyyy-MM-dd']);\n// or guard:\nconst formats = userFormats.length ? userFormats : ['yyyy-MM-dd'];\nadapter.parse('2024-01-15', formats);","handlingStrategy":"validation","validationCode":"const formats: string | string[] = getConfiguredParseFormats();\nconst list = Array.isArray(formats) ? formats : [formats];\nif (!list.length) throw new Error('parse requires at least one format');\nadapter.parse(value, list);","typeGuard":"function hasFormats(f: string | string[]): f is string | [string, ...string[]] {\n  return typeof f === 'string' ? f.length > 0 : f.length > 0;\n}","tryCatchPattern":"try {\n  return adapter.parse(value, formats);\n} catch (e) {\n  if (e.message.includes('Formats array must not be empty')) return null;\n  throw e;\n}","preventionTips":["Never pass an empty array to parse; use undefined to trigger the ISO-8601 fallback.","Keep a non-empty default format list in MAT_DATE_FORMATS.","When building format lists dynamically, always provide a fallback entry.","Validate config at app startup, not at parse time."],"tags":["angular-material","date-fns","date-parsing","invalid-argument","developer-error"],"backgroundTag":"empty-formats-array","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}