{"record":{"id":"432aee65996573f2","repo":"actualbudget/actual","slug":"invalid-date-format-provided","errorCode":null,"errorMessage":"Invalid date format provided","messagePattern":"Invalid date format provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts","lineNumber":62,"sourceCode":"    let endDay: Date;\n    try {\n      startDay = d.parse(\n        monthUtils.firstDayOfMonth(start),\n        '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      }","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts#L44-L80","documentation":"summarySpreadsheet parses the start/end month strings into Date objects using monthUtils helpers plus date-fns d.parse with 'yyyy-MM-dd'. If those helpers or the parse throw (malformed input), the error is caught and rethrown as 'Invalid date format provided'. It signals the caller that the date strings supplied to the report are unparseable.","triggerScenarios":"Calling summarySpreadsheet with start or end that is not a valid yyyy-MM month string (e.g. 'foo', '2024-1', empty string), causing monthUtils.firstDayOfMonth/getMonth/lastDayOfMonth or d.parse to throw.","commonSituations":"Corrupted date range stored in a saved report; an integration passing full ISO timestamps ('2024-05-01T00:00:00Z') or slash-formatted dates where a month string is expected; timezone-related string munging before the call.","solutions":["Inspect and correct the start/end values to valid 'yyyy-MM' month strings","Validate with /^\\d{4}-\\d{2}$/ (and a real month 01-12) before calling summarySpreadsheet","If dates come from a saved report, edit the report's date range in the UI to reset them","Wrap the call in try/catch and fall back to a sane default range"],"exampleFix":"// before\nsummarySpreadsheet('2024-05-01T00:00:00Z', end, conditions, op, content, locale);\n// after\nsummarySpreadsheet('2024-05', end, conditions, op, content, locale); // yyyy-MM month strings","handlingStrategy":"validation","validationCode":"const isValidMonth = (s: string) => /^\\d{4}-(0[1-9]|1[0-2])$/.test(s);\nif (!isValidMonth(start) || !isValidMonth(end)) throw new RangeError('start/end must be yyyy-MM month strings');","typeGuard":"function isMonthString(v: unknown): v is string {\n  return typeof v === 'string' && /^\\d{4}-(0[1-9]|1[0-2])$/.test(v);\n}","tryCatchPattern":"try {\n  await summarySpreadsheet(start, end, conditions, op, content, locale)(spreadsheet, setData);\n} catch (e) {\n  if (e instanceof Error && /Invalid date (format|values)/.test(e.message)) {\n    console.warn('Bad report range, using default', { start, end });\n  } else throw e;\n}","preventionTips":["Pass month strings (yyyy-MM), never ISO timestamps or locale-formatted dates","Sanitize URL/config-supplied date params before building reports","Prefer monthUtils.firstDayOfMonth/lastDayOfMonth over manual date math","Validate report ranges right after deserializing saved reports"],"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"}