phacility/phabricator · error · Exception

RRULE INTERVAL "%s" is invalid: interval must be 1 or more.

Error message

RRULE INTERVAL "%s" is invalid: interval must be 1 or more.

What it means

setInterval() rejects values below 1. An interval of 0 or negative would mean 'every occurrence multiplied by zero' or time travel, both meaningless under RFC 5545; interval 1 (every occurrence) is the minimum.

Source

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

  public function getFrequency() {
    return $this->frequency;
  }

  public function getFrequencyScale() {
    return $this->frequencyScale;
  }

  public function setInterval($interval) {
    if (!is_int($interval)) {
      throw new Exception(
        pht(
          'RRULE INTERVAL "%s" is invalid: interval must be an integer.',
          $interval));
    }

    if ($interval < 1) {
      throw new Exception(
        pht(
          'RRULE INTERVAL "%s" is invalid: interval must be 1 or more.',
          $interval));
    }

    $this->interval = $interval;
    return $this;
  }

  public function getInterval() {
    return $this->interval;
  }

  public function setBySecond(array $by_second) {
    $this->assertByRange('BYSECOND', $by_second, 0, 60);
    $this->bySecond = array_fuse($by_second);
    return $this;
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Set INTERVAL to 1, or drop the INTERVAL part (1 is the default).
  2. Clamp external input: $interval = max(1, (int)$interval) when processing untrusted ICS data.
  3. Add a unit test asserting interval >= 1 wherever intervals are computed.

Example fix

// before
$rule->setInterval(0);
// after
$rule->setInterval(1);
Defensive patterns

Strategy: validation

Validate before calling

$interval = (int) idx($dict, 'INTERVAL', 1);
if ($interval < 1) {
  $interval = 1; // or unset($dict['INTERVAL']); 1 is the default anyway
}
$dict['INTERVAL'] = $interval;

Type guard

function isValidRruleInterval($interval) {
  return is_int($interval) && $interval >= 1;
}

Prevention

When it happens

Trigger: An ICS RRULE with INTERVAL=0; setInterval(0) or setInterval(-3); computed intervals that can hit zero (e.g. unit conversion dividing by an unset value).

Common situations: Broken calendar exports with INTERVAL=0; forms defaulting to 0; arithmetic bugs producing 0/negative intervals.

Related errors


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