{"record":{"id":"8b4edce12ee972e5","repo":"angular/components","slug":"nativedateadapter-cannot-format-invalid-date","errorCode":null,"errorMessage":"NativeDateAdapter: Cannot format invalid date.","messagePattern":"NativeDateAdapter: Cannot format invalid date\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/material/core/datetime/native-date-adapter.ts","lineNumber":165,"sourceCode":"    return result;\n  }\n\n  today(): Date {\n    return new Date();\n  }\n\n  parse(value: any, parseFormat?: any): Date | null {\n    // We have no way using the native JS Date to set the parse format or locale, so we ignore these\n    // parameters.\n    if (typeof value == 'number') {\n      return new Date(value);\n    }\n    return value ? new Date(Date.parse(value)) : null;\n  }\n\n  format(date: Date, displayFormat: Object): string {\n    if (!this.isValid(date)) {\n      throw Error('NativeDateAdapter: Cannot format invalid date.');\n    }\n\n    const dtf = new Intl.DateTimeFormat(this.locale, {...displayFormat, timeZone: 'utc'});\n    return this._format(dtf, date);\n  }\n\n  addCalendarYears(date: Date, years: number): Date {\n    return this.addCalendarMonths(date, years * 12);\n  }\n\n  addCalendarMonths(date: Date, months: number): Date {\n    let newDate = this._createDateWithOverflow(\n      this.getYear(date),\n      this.getMonth(date) + months,\n      this.getDate(date),\n    );\n\n    // It's possible to wind up in the wrong month if the original month has more days than the new","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/core/datetime/native-date-adapter.ts#L147-L183","documentation":"NativeDateAdapter.format first checks isValid(date) (an Invalid Date is Date.parse/NaN-based) and throws rather than emitting 'Invalid Date' strings into the UI. _format (internal formatting path) is the typical caller.","triggerScenarios":"Calling adapter.format() with an invalid Date — e.g. new Date(undefined), new Date('garbage'), or a Date produced by a failed parse — or rendering a null/coerced-undefined value through formatDate paths.","commonSituations":"Datepipe-like formatting of user-typed dates from matDatepicker inputs that failed parsing; backend returning empty/undefined strings coerced to Date; timezone/locale parsing mismatches producing Invalid Date.","solutions":["Check adapter.isValid(date) before formatting and render a fallback string (e.g. '--') for invalid values.","Fix the parsing step that produced the invalid Date; use adapter.parse() instead of new Date(string).","Handle null/undefined at the component level before calling format."],"exampleFix":"// before\nconst label = adapter.format(new Date(inputValue), displayFormat);\n// after\nconst parsed = adapter.parse(inputValue, parseFormat);\nconst label = parsed && adapter.isValid(parsed) ? adapter.format(parsed, displayFormat) : '--';","handlingStrategy":"type-guard","validationCode":"const date = adapter.parse(value, parseFormat);\nif (!date || !adapter.isValid(date)) {\n  return '--'; // skip formatting\n}\nconst label = adapter.format(date, displayFormat);","typeGuard":"function isValidDate(d: unknown): d is Date {\n  return d instanceof Date && !isNaN(d.getTime());\n}","tryCatchPattern":"try {\n  label = adapter.format(date, displayFormat);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Cannot format invalid date')) {\n    label = '--';\n  } else { throw e; }\n}","preventionTips":["Always run adapter.isValid before format.","Use adapter.parse rather than new Date(string) for user input.","Render explicit placeholders for null/invalid dates in templates."],"tags":["angular-material","date-adapter","invalid-date","formatting"],"backgroundTag":"cannot-format-invalid-date","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}