{"record":{"id":"840106027716aa7a","repo":"actualbudget/actual","slug":"invalid-start-date-format","errorCode":null,"errorMessage":"Invalid start date format","messagePattern":"Invalid start date format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/components/reports/spreadsheets/calendar-spreadsheet.ts","lineNumber":62,"sourceCode":"        },\n      );\n      filters = filtersLocal;\n    } catch (error) {\n      console.error('Failed to make filters from conditions:', error);\n      filters = [];\n    }\n    const conditionsOpKey = conditionsOp === 'or' ? '$or' : '$and';\n\n    let startDay: Date;\n    try {\n      startDay = d.parse(\n        monthUtils.firstDayOfMonth(start),\n        'yyyy-MM-dd',\n        new Date(),\n      );\n    } catch (error) {\n      console.error('Failed to parse start date:', error);\n      throw new Error('Invalid start date format');\n    }\n\n    let endDay: Date;\n    try {\n      endDay = d.parse(\n        monthUtils.lastDayOfMonth(end),\n        'yyyy-MM-dd',\n        new Date(),\n      );\n    } catch (error) {\n      console.error('Failed to parse end date:', error);\n      throw new Error('Invalid end date format');\n    }\n\n    const makeRootQuery = () =>\n      q('transactions')\n        .filter({\n          $and: [","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/components/reports/spreadsheets/calendar-spreadsheet.ts#L44-L80","documentation":"calendarSpreadsheet builds the data loader for the calendar report. It parses the `start` (and `end`) month strings with date-fns' d.parse using the 'yyyy-MM-dd' format; if parsing fails it logs the underlying error and rethrows this clearer 'Invalid start date format' error. It means the month string supplied to the calendar report could not be interpreted as a valid date.","triggerScenarios":"Calling calendarSpreadsheet (or the report widget that supplies its params) with a start value that is not a 'yyyy-MM-dd'-parseable month — e.g. an empty string, undefined coerced to a string, a localized date like '01/2024', or a truncated value like '2024'.","commonSituations":"Report date-range state not yet initialized when the calendar renders (empty string passed on first render); user preferences or report configs persisted with a different date format; a timezone/locale-dependent code path producing non-ISO month strings.","solutions":["Log the start value at the call site to confirm what string was passed.","Ensure the caller passes a valid 'yyyy-MM-dd' month (e.g. monthUtils.currentMonth() or monthUtils.subMonths(curMonth, n)).","Guard the report component to render only after the date range state is initialized (avoid empty-string start).","Migrate any persisted report range config to the ISO 'yyyy-MM-dd' format."],"exampleFix":"// before\nconst start = reportConfig.startMonth; // may be '' or '2024/01'\n// after\nconst start =\n  /^\\d{4}-\\d{2}$/.test(reportConfig.startMonth ?? '')\n    ? reportConfig.startMonth\n    : monthUtils.currentMonth();","handlingStrategy":"validation","validationCode":"const ISO_MONTH = /^\\d{4}-\\d{2}-\\d{2}$/;\nif (!ISO_MONTH.test(start)) {\n  throw new Error(`start must be yyyy-MM-dd, got: ${JSON.stringify(start)}`);\n}\ncalendarSpreadsheet(start, end, conditions, conditionsOp, firstDayOfWeekIdx);","typeGuard":"function isIsoDateString(v: unknown): v is string {\n  return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(v) && !Number.isNaN(d.parseISO(v).getTime());\n}","tryCatchPattern":"try {\n  useCalendarReport(start, end);\n} catch (err) {\n  if (String(err).includes('Invalid start date format')) {\n    setMonth(monthUtils.currentMonth()); // reset to a valid month and retry\n    return;\n  }\n  throw err;\n}","preventionTips":["Always source month strings from monthUtils helpers (currentMonth, subMonths, addMonths) which emit 'yyyy-MM'.","Never pass empty/uninitialized date-range state to the calendar report; gate rendering on initialization.","Validate persisted report date ranges with a regex before use.","Prefer d.parseISO/d.parse with explicit format and isNaN checks on the result reference date."],"tags":["date-parsing","reports","calendar","date-fns"],"backgroundTag":"invalid-date-format","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}