phacility/phabricator · error · Exception
Value "%s" in RRULE "%s" parameter is invalid: values must b
Error message
Value "%s" in RRULE "%s" parameter is invalid: values must be integers.
What it means
All RRULE filter setters (BYMONTH, BYHOUR, BYSETPOS, etc.) funnel through assertByRange(), which requires every value to be a real PHP integer. Even a numeric string like '5' is rejected, because the string '0' is truthy in PHP loose comparisons and the engine relies on integer semantics throughout evaluation.
Source
Thrown at src/applications/calendar/parser/data/PhutilCalendarRecurrenceRule.php:1587
}
}
sort($select);
$select = array_unique($select);
return array_select_keys($values, $select);
}
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));
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Cast every value with intval() (or array_map('intval', $values)) before calling the setter
- Parse complete RRULE text through PhutilCalendarRecurrenceRule::newFromRRule() instead of assembling parts by hand
- Add a unit assertion in tests that setters receive int arrays
Example fix
// before
$rule->setByMonthDay(explode(',', $request->getStr('monthdays')));
// after
$rule->setByMonthDay(
array_map('intval', explode(',', $request->getStr('monthdays')))); Defensive patterns
Strategy: type-guard
Validate before calling
$values = array_map('intval', $values);
if (array_filter($values, 'is_string')) {
throw new Exception('RRULE values must be integers.');
} Type guard
function isIntList(array $values) {
foreach ($values as $value) {
if (!is_int($value)) {
return false;
}
}
return true;
}
if (!isIntList($monthdays)) {
$monthdays = array_map('intval', $monthdays);
} Try / catch
try {
$rule->setByMonthDay($values);
} catch (Exception $ex) {
throw new Exception('Non-integer recurrence values in user input.');
} Prevention
- Never feed explode() or JSON-decoded values into setters without array_map('intval', ...)
- Prefer parsing complete RRULE text with newFromRRule() over hand-assembling rules
- Remember PHP's is_int('5') is false — cast explicitly, do not rely on coercion
When it happens
Trigger: Calling setByMonthDay(array('10','20')), setByHour(explode(',', $user_input)), or any setter fed with values that came from HTTP request data, explode() output, or JSON decoding without casting. Note that parsing an RRULE string via newFromRRule() already produces ints, so this only bites programmatic construction.
Common situations: Glue code that splits a comma-separated user string straight into a setter; data round-tripped through JSON with string values; refactors that replaced intval() with array keys from config arrays.
Related errors
- RRULE dictionary includes unknown key "%s". Expected keys ar
- 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.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/9a06514488b43215.
Report an issue: GitHub.