phacility/phabricator · error · Exception
RRULE dictionary includes unknown key "%s". Expected keys ar
Error message
RRULE dictionary includes unknown key "%s". Expected keys are: %s.
What it means
PhutilCalendarRecurrenceRule::newFromDictionary() validates every key of the supplied dictionary against the known RRULE properties (FREQ, INTERVAL, BYSECOND, BYMINUTE, BYHOUR, BYDAY, BYMONTH, BYMONTHDAY, BYEARDAY, BYWEEKNO, BYSETPOS, WKST, UNTIL, COUNT). Any unrecognized key aborts with the expected-key list.
Source
Thrown at src/applications/calendar/parser/data/PhutilCalendarRecurrenceRule.php:186
'INTERVAL',
'BYSECOND',
'BYMINUTE',
'BYHOUR',
'BYDAY',
'BYMONTH',
'BYMONTHDAY',
'BYYEARDAY',
'BYWEEKNO',
'BYSETPOS',
'WKST',
'UNTIL',
'COUNT',
));
}
foreach ($dict as $key => $value) {
if (empty($expect[$key])) {
throw new Exception(
pht(
'RRULE dictionary includes unknown key "%s". Expected keys '.
'are: %s.',
$key,
implode(', ', array_keys($expect))));
}
}
$rrule = id(new self())
->setFrequency(idx($dict, 'FREQ'))
->setInterval(idx($dict, 'INTERVAL', 1))
->setBySecond(idx($dict, 'BYSECOND', array()))
->setByMinute(idx($dict, 'BYMINUTE', array()))
->setByHour(idx($dict, 'BYHOUR', array()))
->setByDay(idx($dict, 'BYDAY', array()))
->setByMonth(idx($dict, 'BYMONTH', array()))
->setByMonthDay(idx($dict, 'BYMONTHDAY', array()))
->setByYearDay(idx($dict, 'BYYEARDAY', array()))View on GitHub (pinned to 5720a38cfe)
Solutions
- Filter the dict to known keys first: array_intersect_key($dict, array_flip($knownKeys)).
- Uppercase keys: array_change_key_case($dict, CASE_UPPER).
- Strip unsupported extension properties (BYEASTER, X-*) before constructing the rule.
Example fix
// before $rule = PhutilCalendarRecurrenceRule::newFromDictionary($dict); // $dict has 'BYEASTER' // after unset($dict['BYEASTER']); $dict = array_change_key_case($dict, CASE_UPPER); $rule = PhutilCalendarRecurrenceRule::newFromDictionary($dict);
Defensive patterns
Strategy: type-guard
Validate before calling
$known = array('FREQ','INTERVAL','BYSECOND','BYMINUTE','BYHOUR','BYDAY',
'BYMONTH','BYMONTHDAY','BYYEARDAY','BYWEEKNO','BYSETPOS','WKST','UNTIL','COUNT');
$dict = array_change_key_case((array)$dict, CASE_UPPER);
$dict = array_intersect_key($dict, array_flip($known)); // drop unknown keys
$rule = PhutilCalendarRecurrenceRule::newFromDictionary($dict); Type guard
function rruleDictHasKnownKeys(array $dict) {
$known = array_flip(array('FREQ','INTERVAL','BYSECOND','BYMINUTE','BYHOUR',
'BYDAY','BYMONTH','BYMONTHDAY','BYYEARDAY','BYWEEKNO','BYSETPOS','WKST',
'UNTIL','COUNT'));
return count(array_diff_key(array_change_key_case($dict, CASE_UPPER), $known)) === 0;
} Try / catch
try {
$rule = PhutilCalendarRecurrenceRule::newFromDictionary($dict);
} catch (Exception $ex) {
// log the offending key from the message and drop it, then retry once
phlog($ex->getMessage());
unset($dict[$badKey]);
} Prevention
- Uppercase and filter dict keys against the known RRULE set before constructing rules.
- Strip nonstandard extension properties (BYEASTER, X-*) at ICS ingest time.
- Do not round-trip RRULE dicts through storage that lowercases keys.
When it happens
Trigger: A dict containing 'BYEASTER' (common non-standard extension), lowercase keys like 'freq', a typo such as 'COUNTS', or an ICS parser leaking 'X-...' extension properties into the RRULE dict.
Common situations: Feeding raw parsed ICS RRULE lines into the constructor; vendors adding private extensions; case mismatches after lowercasing keys for storage.
Related errors
- Unexpected value "%s" in "%s" RULE property: expected an int
- Unexpected value "%s" in "%s" RRULE property: expected only
- Weekday "%s" is not a valid weekday constant. Valid constant
- RRULE COUNT value "%s" is invalid: count must be at least 1.
- RRULE FREQ "%s" is invalid. Valid frequencies are: %s.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/020480463cae4a21.
Report an issue: GitHub.