{"record":{"id":"1fbc17e160356cae","repo":"actualbudget/actual","slug":"invalid-date-values-provided","errorCode":null,"errorMessage":"Invalid date values provided","messagePattern":"Invalid date values provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts","lineNumber":66,"sourceCode":"        'yyyy-MM-dd',\n        new Date(),\n      );\n\n      endDay = d.parse(\n        monthUtils.getMonth(end) ===\n          monthUtils.getMonth(monthUtils.currentDay())\n          ? monthUtils.currentDay()\n          : monthUtils.lastDayOfMonth(end),\n        'yyyy-MM-dd',\n        new Date(),\n      );\n    } catch (error) {\n      console.error('Error parsing dates:', error);\n      throw new Error('Invalid date format provided');\n    }\n\n    if (!d.isValid(startDay) || !d.isValid(endDay)) {\n      throw new Error('Invalid date values provided');\n    }\n\n    if (d.isAfter(startDay, endDay)) {\n      throw new Error('Start date must be before or equal to end date.');\n    }\n\n    const getOneDatePerMonth = (start: Date, end: Date) => {\n      const months = [];\n      let currentDate = d.startOfMonth(start);\n\n      while (!d.isSameMonth(currentDate, end)) {\n        months.push(currentDate);\n        currentDate = d.addMonths(currentDate, 1);\n      }\n      months.push(end);\n\n      return months;\n    };","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts#L48-L84","documentation":"After parsing, summarySpreadsheet checks d.isValid on both parsed dates. date-fns d.parse returns an Invalid Date object instead of throwing for some malformed inputs, so this second check catches strings that parsed without throwing but produced invalid Dates. The throw guarantees the report never queries with meaningless date bounds.","triggerScenarios":"Passing a syntactically plausible but nonexistent date, e.g. '2024-02-30' or month '2024-00'/'2024-13' that monthUtils passes through and d.parse turns into an Invalid Date.","commonSituations":"Hand-edited report configs or URL query params supplying out-of-range months; migration code writing invalid month values; user input validated only superficially before constructing the report.","solutions":["Verify the start/end values are real calendar months (month between 01 and 12)","Pre-validate with a regex plus a range check, or use d.parse + d.isValid on your side before calling","Re-save the report's date range via the UI if the value is persisted","Catch this error and render an 'invalid date range' state instead of crashing the dashboard"],"exampleFix":"// before\nsummarySpreadsheet('2024-13', end, ...); // month 13 -> Invalid Date\n// after\nconst start = '2024-13';\nif (!/^(\\d{4})-(0[1-9]|1[0-2])$/.test(start)) throw new Error('start must be a real yyyy-MM month');\nsummarySpreadsheet(start, end, ...);","handlingStrategy":"validation","validationCode":"function isRealMonth(s: string) {\n  const m = s.match(/^(\\d{4})-(\\d{2})$/);\n  if (!m) return false;\n  const month = Number(m[2]);\n  return month >= 1 && month <= 12;\n}\nif (!isRealMonth(start) || !isRealMonth(end)) throw new RangeError('month out of range');","typeGuard":"function isParsableDate(v: unknown): v is string {\n  if (typeof v !== 'string') return false;\n  return !Number.isNaN(new Date(v + '-01').getTime());\n}","tryCatchPattern":"try {\n  await builder(spreadsheet, setData);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Invalid date values provided') {\n    setData(zeroSummary);\n  } else throw e;\n}","preventionTips":["Reject out-of-range months (00, 13+) at input boundaries like URL params","Round-trip validate: parse then isValid before persisting a range","Use a date picker component instead of free-text input for ranges","Add schema validation to stored report configs"],"tags":["date-parsing","reports","validation"],"backgroundTag":"invalid-date-format","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}