actualbudget/actual · error

Invalid date values provided

Error message

Invalid date values provided

What it means

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.

Source

Thrown at packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts:66

        'yyyy-MM-dd',
        new Date(),
      );

      endDay = d.parse(
        monthUtils.getMonth(end) ===
          monthUtils.getMonth(monthUtils.currentDay())
          ? monthUtils.currentDay()
          : monthUtils.lastDayOfMonth(end),
        'yyyy-MM-dd',
        new Date(),
      );
    } catch (error) {
      console.error('Error parsing dates:', error);
      throw new Error('Invalid date format provided');
    }

    if (!d.isValid(startDay) || !d.isValid(endDay)) {
      throw new Error('Invalid date values provided');
    }

    if (d.isAfter(startDay, endDay)) {
      throw new Error('Start date must be before or equal to end date.');
    }

    const getOneDatePerMonth = (start: Date, end: Date) => {
      const months = [];
      let currentDate = d.startOfMonth(start);

      while (!d.isSameMonth(currentDate, end)) {
        months.push(currentDate);
        currentDate = d.addMonths(currentDate, 1);
      }
      months.push(end);

      return months;
    };

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Verify the start/end values are real calendar months (month between 01 and 12)
  2. Pre-validate with a regex plus a range check, or use d.parse + d.isValid on your side before calling
  3. Re-save the report's date range via the UI if the value is persisted
  4. Catch this error and render an 'invalid date range' state instead of crashing the dashboard

Example fix

// before
summarySpreadsheet('2024-13', end, ...); // month 13 -> Invalid Date
// after
const start = '2024-13';
if (!/^(\d{4})-(0[1-9]|1[0-2])$/.test(start)) throw new Error('start must be a real yyyy-MM month');
summarySpreadsheet(start, end, ...);
Defensive patterns

Strategy: validation

Validate before calling

function isRealMonth(s: string) {
  const m = s.match(/^(\d{4})-(\d{2})$/);
  if (!m) return false;
  const month = Number(m[2]);
  return month >= 1 && month <= 12;
}
if (!isRealMonth(start) || !isRealMonth(end)) throw new RangeError('month out of range');

Type guard

function isParsableDate(v: unknown): v is string {
  if (typeof v !== 'string') return false;
  return !Number.isNaN(new Date(v + '-01').getTime());
}

Try / catch

try {
  await builder(spreadsheet, setData);
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid date values provided') {
    setData(zeroSummary);
  } else throw e;
}

Prevention

When it happens

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

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

Related errors


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