actualbudget/actual · error

Invalid start date format

Error message

Invalid start date format

What it means

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.

Source

Thrown at packages/desktop-client/src/components/reports/spreadsheets/calendar-spreadsheet.ts:62

        },
      );
      filters = filtersLocal;
    } catch (error) {
      console.error('Failed to make filters from conditions:', error);
      filters = [];
    }
    const conditionsOpKey = conditionsOp === 'or' ? '$or' : '$and';

    let startDay: Date;
    try {
      startDay = d.parse(
        monthUtils.firstDayOfMonth(start),
        'yyyy-MM-dd',
        new Date(),
      );
    } catch (error) {
      console.error('Failed to parse start date:', error);
      throw new Error('Invalid start date format');
    }

    let endDay: Date;
    try {
      endDay = d.parse(
        monthUtils.lastDayOfMonth(end),
        'yyyy-MM-dd',
        new Date(),
      );
    } catch (error) {
      console.error('Failed to parse end date:', error);
      throw new Error('Invalid end date format');
    }

    const makeRootQuery = () =>
      q('transactions')
        .filter({
          $and: [

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Log the start value at the call site to confirm what string was passed.
  2. Ensure the caller passes a valid 'yyyy-MM-dd' month (e.g. monthUtils.currentMonth() or monthUtils.subMonths(curMonth, n)).
  3. Guard the report component to render only after the date range state is initialized (avoid empty-string start).
  4. Migrate any persisted report range config to the ISO 'yyyy-MM-dd' format.

Example fix

// before
const start = reportConfig.startMonth; // may be '' or '2024/01'
// after
const start =
  /^\d{4}-\d{2}$/.test(reportConfig.startMonth ?? '')
    ? reportConfig.startMonth
    : monthUtils.currentMonth();
Defensive patterns

Strategy: validation

Validate before calling

const ISO_MONTH = /^\d{4}-\d{2}-\d{2}$/;
if (!ISO_MONTH.test(start)) {
  throw new Error(`start must be yyyy-MM-dd, got: ${JSON.stringify(start)}`);
}
calendarSpreadsheet(start, end, conditions, conditionsOp, firstDayOfWeekIdx);

Type guard

function isIsoDateString(v: unknown): v is string {
  return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(v) && !Number.isNaN(d.parseISO(v).getTime());
}

Try / catch

try {
  useCalendarReport(start, end);
} catch (err) {
  if (String(err).includes('Invalid start date format')) {
    setMonth(monthUtils.currentMonth()); // reset to a valid month and retry
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/840106027716aa7a. Report an issue: GitHub.