hcengineering/platform · error

Invalid recurring rule frequency

Error message

Invalid recurring rule frequency

What it means

generateRecurringValues switches on the recurrence rule's frequency (DAILY, WEEKLY, MONTHLY, YEARLY). Any other frequency value falls through to default and throws, since no expansion strategy exists for it.

Source

Thrown at plugins/calendar/src/utils.ts:44

export function generateRecurringValues (
  rule: RecurringRule,
  startDate: Timestamp,
  from: Timestamp,
  to: Timestamp
): Timestamp[] {
  const currentDate = new Date(startDate)
  switch (rule.freq) {
    case 'DAILY':
      return generateDailyValues(rule, currentDate, from, to)
    case 'WEEKLY':
      return generateWeeklyValues(rule, currentDate, from, to)
    case 'MONTHLY':
      return generateMonthlyValues(rule, currentDate, from, to)
    case 'YEARLY':
      return generateYearlyValues(rule, currentDate, from, to)
    default:
      throw new Error('Invalid recurring rule frequency')
  }
}

function generateDailyValues (rule: RecurringRule, currentDate: Date, from: Timestamp, to: Timestamp): Timestamp[] {
  const values: Timestamp[] = []
  const { count, endDate, interval } = rule
  const { bySetPos } = rule
  let i = 0

  while (true) {
    if (bySetPos == null || bySetPos.includes(getSetPos(currentDate))) {
      const res = currentDate.getTime()
      if (currentDate.getTime() > to) break
      if (endDate != null && currentDate.getTime() > endDate) break
      if (res >= from && res <= to) {
        values.push(res)
      }
      i++

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Normalize rule.frequency to an uppercase supported value (DAILY/WEEKLY/MONTHLY/YEARLY) before saving
  2. Map unsupported frequencies (HOURLY etc.) to the closest supported rule at import time
  3. Validate recurrence rules on input with a whitelist of allowed frequencies

Example fix

// before
const rule = { freq: 'daily', ... } // lowercase, throws
// after
const rule = { freq: String(raw.freq).toUpperCase() as 'DAILY'|'WEEKLY'|'MONTHLY'|'YEARLY', ... }
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'] as const
if (!SUPPORTED.includes(rule.freq.toUpperCase() as any)) {
  throw new Error(`Unsupported frequency: ${rule.freq}`)
}

Type guard

const isSupportedFrequency = (f: string): f is 'DAILY'|'WEEKLY'|'MONTHLY'|'YEARLY' =>
  ['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'].includes(f.toUpperCase())

Try / catch

try {
  values = generateRecurringValues(rule, currentDate, from, to)
} catch (err) {
  if ((err as Error).message === 'Invalid recurring rule frequency') {
    values = [] // treat as non-recurring or normalize rule
  } else throw err
}

Prevention

When it happens

Trigger: A calendar event has a RecurringRule whose freq property is not one of the four supported uppercase values — e.g. lowercase 'daily', a typo, or an unsupported iCalendar FREQ like HOURLY/SECONDLY stored in the rule.

Common situations: Importing iCalendar files from other systems with exotic frequencies; manual rule construction with wrong casing; older/newer data versions with frequencies this build does not support.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/495f70185b939847. Report an issue: GitHub.