phacility/phabricator · error · Exception

Value "%s" in RRULE "%s" parameter is invalid: it must be be

Error message

Value "%s" in RRULE "%s" parameter is invalid: it must be between %s and %s.

What it means

assertByRange() bounds every value in an RRULE parameter list to a legal range (e.g. BYMONTH 1-12, BYWEEKNO -53..53, BYHOUR 0-23). Any value below the minimum or above the maximum for that parameter is rejected immediately, mirroring the numeric limits RFC5545 defines for each rule part.

Source

Thrown at src/applications/calendar/parser/data/PhutilCalendarRecurrenceRule.php:1596

  private function assertByRange(
    $source,
    array $values,
    $min,
    $max,
    $allow_zero = true) {

    foreach ($values as $value) {
      if (!is_int($value)) {
        throw new Exception(
          pht(
            'Value "%s" in RRULE "%s" parameter is invalid: values must be '.
            'integers.',
            $value,
            $source));
      }

      if ($value < $min || $value > $max) {
        throw new Exception(
          pht(
            'Value "%s" in RRULE "%s" parameter is invalid: it must be '.
            'between %s and %s.',
            $value,
            $source,
            $min,
            $max));
      }

      if (!$value && !$allow_zero) {
        throw new Exception(
          pht(
            'Value "%s" in RRULE "%s" parameter is invalid: it must not '.
            'be zero.',
            $value,
            $source));
      }
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Clamp or correct the offending values to the RFC range for that parameter (BYMONTH 1-12, BYMONTHDAY -31..31, BYHOUR 0-23, etc.)
  2. Validate user-supplied ranges before they reach the rule object
  3. Re-check the RRULE string for typos like BYMONTH=13 or BYMONTHDAY=32

Example fix

// before
$rrule = 'FREQ=MONTHLY;BYMONTHDAY=32';

// after
$rrule = 'FREQ=MONTHLY;BYMONTHDAY=31';
Defensive patterns

Strategy: validation

Validate before calling

$ranges = array(
  'BYMONTH' => array(1, 12),
  'BYMONTHDAY' => array(-31, 31),
  'BYYEARDAY' => array(-366, 366),
  'BYWEEKNO' => array(-53, 53),
  'BYHOUR' => array(0, 23),
  'BYMINUTE' => array(0, 59),
  'BYSECOND' => array(0, 60),
);
foreach ($ranges as $key => $bounds) {
  if (isset($parts[$key])) {
    foreach (explode(',', $parts[$key]) as $value) {
      $value = (int)$value;
      if ($value < $bounds[0] || $value > $bounds[1]) {
        throw new Exception($key.' value out of range: '.$value);
      }
    }
  }
}

Try / catch

try {
  $rule = PhutilCalendarRecurrenceRule::newFromRRule($rrule);
} catch (Exception $ex) {
  // Report which parameter and value failed by echoing $ex->getMessage().
}

Prevention

When it happens

Trigger: setByMonthDay(array(0, 32)) or an RRULE 'FREQ=MONTHLY;BYMONTHDAY=32'; setByMonth(array(13)); setByHour(array(24)); setByWeekNumber(array(54)); setBySetPosition(array(400)).

Common situations: Off-by-one mistakes when converting human input ('every month 1-13' style quarter notation); rules imported from producers with lax validation; unit tests probing boundary values.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/7cb0277c4029b927. Report an issue: GitHub.