{"record":{"id":"920ab00b70cfa33d","repo":"xai-org/x-algorithm","slug":"scheduledevent-config-eventtype-intervalmillis","errorCode":null,"errorMessage":"ScheduledEvent ${config.eventType} intervalMillis must be a postivie value.","messagePattern":"ScheduledEvent (.+?) intervalMillis must be a postivie value\\.","errorType":"validation","errorClass":"ConfigFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/scala/com/twitter/botmaker/runtime/config/ScheduledEventConfigs.scala","lineNumber":36,"sourceCode":"  ): ScheduledEventConfig = {\n    context.getRuntime.addScheduledEvent(config)\n    config\n  }\n}\n\ntrait ScheduledEventConfigs extends ServiceConfigs with EventTypeConfigs {\n\n  private final val scheduledEvents = mutable.ArrayBuffer[ScheduledEventConfig]()\n\n  final def getScheduledEvents: Seq[ScheduledEventConfig] = scheduledEvents.toSeq\n\n  final def addScheduledEvent(config: ScheduledEventConfig): Option[BotMakerEventTypeConfig] = {\n\n    unique(ScheduledEvent, config.eventType)\n    unique(Endpoint, config.eventType)\n\n    if (config.intervalMillis <= 0) {\n      throw ConfigFailure(\n        s\"ScheduledEvent ${config.eventType} intervalMillis must be a postivie value.\"\n      )\n    }\n\n    scheduledEvents.append(config)\n\n    addEventType(\n      new BotMakerEventTypeConfig()\n        .setEventType(config.eventType)\n    )\n\n  }\n\n  override def debug(dbg: RuntimeDebugger): Unit = {\n    super.debug(dbg)\n\n    dbg.open(\"scheduledEvents\", scheduledEvents) foreach { d =>\n      scheduledEvents foreach { se => d.info(se.eventType, se.toString) }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/scala/com/twitter/botmaker/runtime/config/ScheduledEventConfigs.scala#L18-L54","documentation":"When registering a ScheduledEventConfig, BotMaker requires intervalMillis (the period between event firings) to be strictly positive. A zero or negative interval would cause an infinite loop or nonsensical scheduling, so ConfigFailure is thrown with the offending eventType in the message (note the typo 'postivie' in the source).","triggerScenarios":"Calling addScheduledEvent with a ScheduledEventConfig whose intervalMillis <= 0; the eventType/endpoint uniqueness checks run first, then this interval validation.","commonSituations":"Defaulting intervalMillis to 0 in a case class and forgetting to override; computing the interval from a cron/duration conversion that yields 0; passing seconds instead of milliseconds resulting in truncation to 0.","solutions":["Set intervalMillis to a positive millisecond value appropriate to the event cadence","Check that the code path constructing ScheduledEventConfig actually sets intervalMillis (no default of 0 slipping through)","Add a unit test asserting intervalMillis > 0 for every scheduled event you register"],"exampleFix":"// before\naddScheduledEvent(ScheduledEventConfig(eventType = \"DailyDigest\", intervalMillis = 0))\n\n// after\naddScheduledEvent(ScheduledEventConfig(eventType = \"DailyDigest\", intervalMillis = 86400000L))","handlingStrategy":"validation","validationCode":"def addEvent(cfg):\n    assert cfg.intervalMillis > 0, f\"{cfg.eventType}: intervalMillis must be > 0\"\n    addScheduledEvent(cfg)","typeGuard":null,"tryCatchPattern":"try:\n    addScheduledEvent(cfg)\nexcept ConfigFailure as e:\n    if \"intervalMillis\" in str(e):\n        cfg = cfg.copy(intervalMillis=DEFAULT_INTERVAL_MS); addScheduledEvent(cfg)\n    else:\n        raise","preventionTips":["Never default intervalMillis to 0 in case classes","Validate cadence configs in CI"],"tags":["botmaker","scala","scheduled-events","config-validation"],"backgroundTag":"config-validation-failed","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}