{"record":{"id":"df21384c5ad2dd95","repo":"phacility/phabricator","slug":"rrule-interval-s-is-invalid-interval-must-be-1","errorCode":null,"errorMessage":"RRULE INTERVAL \"%s\" is invalid: interval must be 1 or more.","messagePattern":"RRULE INTERVAL \"(.+?)\" is invalid: interval must be 1 or more\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/calendar/parser/data/PhutilCalendarRecurrenceRule.php","lineNumber":418,"sourceCode":"\n  public function getFrequency() {\n    return $this->frequency;\n  }\n\n  public function getFrequencyScale() {\n    return $this->frequencyScale;\n  }\n\n  public function setInterval($interval) {\n    if (!is_int($interval)) {\n      throw new Exception(\n        pht(\n          'RRULE INTERVAL \"%s\" is invalid: interval must be an integer.',\n          $interval));\n    }\n\n    if ($interval < 1) {\n      throw new Exception(\n        pht(\n          'RRULE INTERVAL \"%s\" is invalid: interval must be 1 or more.',\n          $interval));\n    }\n\n    $this->interval = $interval;\n    return $this;\n  }\n\n  public function getInterval() {\n    return $this->interval;\n  }\n\n  public function setBySecond(array $by_second) {\n    $this->assertByRange('BYSECOND', $by_second, 0, 60);\n    $this->bySecond = array_fuse($by_second);\n    return $this;\n  }","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/calendar/parser/data/PhutilCalendarRecurrenceRule.php#L400-L436","documentation":"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.","triggerScenarios":"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).","commonSituations":"Broken calendar exports with INTERVAL=0; forms defaulting to 0; arithmetic bugs producing 0/negative intervals.","solutions":["Set INTERVAL to 1, or drop the INTERVAL part (1 is the default).","Clamp external input: $interval = max(1, (int)$interval) when processing untrusted ICS data.","Add a unit test asserting interval >= 1 wherever intervals are computed."],"exampleFix":"// before\n$rule->setInterval(0);\n// after\n$rule->setInterval(1);","handlingStrategy":"validation","validationCode":"$interval = (int) idx($dict, 'INTERVAL', 1);\nif ($interval < 1) {\n  $interval = 1; // or unset($dict['INTERVAL']); 1 is the default anyway\n}\n$dict['INTERVAL'] = $interval;","typeGuard":"function isValidRruleInterval($interval) {\n  return is_int($interval) && $interval >= 1;\n}","tryCatchPattern":null,"preventionTips":["Clamp external interval values to >= 1 at ingest.","Drop INTERVAL entirely when the source value is 0 instead of passing it through.","Unit-test interval arithmetic (division/multiplication) for zero results."],"tags":["phutil","calendar","rrule","interval","out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}