phacility/phabricator · error · Exception

Unexpected value "%s" in "%s" RRULE property: expected only

Error message

Unexpected value "%s" in "%s" RRULE property: expected only integers.

What it means

In RRULE dictionary normalization, list-valued integer properties (BYSECOND, BYMINUTE, BYHOUR, BYMONTH, BYMONTHDAY, BYEARDAY, BYWEEKNO, BYSETPOS) require every element to match /^-?\d+$/ - an optionally negative integer. Any non-numeric element (weekday token, decimal, empty string) throws.

Source

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

    foreach ($dict as $key => $value) {
      if (isset($int_values[$key])) {
        // None of these values may be negative.
        if (!preg_match('/^\d+\z/', $value)) {
          throw new Exception(
            pht(
              'Unexpected value "%s" in "%s" RULE property: expected an '.
              'integer.',
              $value,
              $key));
        }
        $dict[$key] = (int)$value;
      }

      if (isset($int_lists[$key])) {
        foreach ($value as $k => $v) {
          if (!preg_match('/^-?\d+\z/', $v)) {
            throw new Exception(
              pht(
                'Unexpected value "%s" in "%s" RRULE property: expected '.
                'only integers.',
                $v,
                $key));
          }
          $value[$k] = (int)$v;
        }
        $dict[$key] = $value;
      }
    }

    return self::newFromDictionary($dict);
  }

  private static function getAllWeekdayConstants() {
    return array_keys(self::getWeekdayIndexMap());
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Keep weekday tokens (SU..SA) only in BYDAY; numeric list fields accept bare integers only.
  2. Normalize lists before use: array_map('trim', $list), strip '+' prefixes, drop empty elements.
  3. Validate every element against ^-?\d+$ and reject the RRULE (or drop the element) before calling newFromDictionary().

Example fix

// before
$dict['BYMONTHDAY'] = array('+1', '');
// after
$dict['BYMONTHDAY'] = array(1);
Defensive patterns

Strategy: type-guard

Validate before calling

$int_lists = array('BYSECOND','BYMINUTE','BYHOUR','BYMONTH',
  'BYMONTHDAY','BYYEARDAY','BYWEEKNO','BYSETPOS');
foreach ($int_lists as $k) {
  if (!isset($dict[$k])) { continue; }
  $clean = array();
  foreach ((array)$dict[$k] as $v) {
    $v = trim((string)$v);
    if ($v !== '' && preg_match('/^-?\d+$/', $v)) {
      $clean[] = (string)(int)$v;
    }
  }
  if ($clean) { $dict[$k] = $clean; } else { unset($dict[$k]); }
}

Type guard

function isIntegerListValue($value) {
  return is_array($value)
    && count($value) > 0
    && !array_filter($value, function ($v) {
      return !preg_match('/^-?\d+$/', trim((string)$v));
     });
}

Try / catch

try {
  $rule = PhutilCalendarRecurrenceRule::newFromDictionary($dict);
} catch (Exception $ex) {
  phlog($ex->getMessage()); // names the bad element and property
  continue;
}

Prevention

When it happens

Trigger: 'BYMONTHDAY' => ['MO'] (weekday token in a numeric-only field), 'BYSETPOS' => ['1.5'], a trailing empty string from exploding '1,2,' on commas.

Common situations: Producers that put weekday tokens into numeric fields; naive explode() of ICS lists leaving empty elements; sign handling like '+1' (fails the regex since + is not allowed).

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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