{"record":{"id":"799dd0e11e5e0775","repo":"xai-org/x-algorithm","slug":"adhoc-runs-require-a-window-pass-date-start-end","errorCode":null,"errorMessage":"Adhoc runs require a window: pass --date START END or --month YYYY-MM (production windows come from statebird via the *Prod scheduled app).","messagePattern":"Adhoc runs require a window: pass --date START END or --month YYYY-MM \\(production windows come from statebird via the \\*Prod scheduled app\\)\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"under-the-hood/scalding/UnderTheHoodDates.scala","lineNumber":22,"sourceCode":"import com.twitter.scalding.DateParser\nimport com.twitter.scalding.DateRange\nimport com.twitter.scalding.RichDate\nimport java.util.Calendar\nimport java.util.TimeZone\n\nobject UnderTheHoodDates {\n\n  def resolve(args: Args): DateRange = {\n    implicit val tz: TimeZone = TimeZone.getTimeZone(\"UTC\")\n    implicit val dp: DateParser = DateParser.default\n    val dates = args.list(\"date\")\n    if (dates.nonEmpty) DateRange.parse(dates)\n    else\n      args\n        .optional(\"month\")\n        .map(monthRange)\n        .getOrElse(\n          throw new IllegalArgumentException(\n            \"Adhoc runs require a window: pass --date START END or --month YYYY-MM \" +\n              \"(production windows come from statebird via the *Prod scheduled app).\"))\n  }\n\n  def monthRange(ym: String): DateRange = {\n    require(ym.matches(\"\"\"\\d{4}-\\d{2}\"\"\"), s\"--month must be YYYY-MM; got '$ym'\")\n    val Array(year, month) = ym.split(\"-\").map(_.toInt)\n    require(month >= 1 && month <= 12, s\"--month has an invalid month: '$ym'\")\n    val cal = utcCal()\n    cal.setLenient(false)\n    cal.clear()\n    cal.set(year, month - 1, 1, 0, 0, 0)\n    val start = cal.getTimeInMillis\n    cal.add(Calendar.MONTH, 1)\n    DateRange(RichDate(start), RichDate(cal.getTimeInMillis - 1L))\n  }\n\n  private def utcCal(): Calendar = Calendar.getInstance(TimeZone.getTimeZone(\"UTC\"))","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/under-the-hood/scalding/UnderTheHoodDates.scala#L4-L40","documentation":"UnderTheHoodDates.getDateRange requires an adhoc time window: either --date START END or --month YYYY-MM must be present. Production runs get their window injected by the statebird-scheduled *Prod app; when neither arg is present the job refuses to run with an unbounded window.","triggerScenarios":"Running an adhoc scalding job with neither --date nor --month; running the non-Prod app locally where statebird does not inject a window; misspelling the flag names so both optionals are empty.","commonSituations":"Local development or one-off backfills where the operator forgot the window; copying a prod launch command but removing the scheduling wrapper; typo'd flags (--dates, --months).","solutions":["Add --date \"2024-01-01 2024-01-02\" (START END) or --month 2024-01 to the job args","Verify flag spelling exactly matches 'date' and 'month'","For production behavior, launch via the statebird-scheduled *Prod app instead of adhoc"],"exampleFix":"# before\nhadoop jar uth.jar com.twitter.uth.Job --output /tmp/out\n# after\nhadoop jar uth.jar com.twitter.uth.Job --date 2024-01-01 2024-01-15 --output /tmp/out","handlingStrategy":"validation","validationCode":"require(args.optional(\"date\").isDefined || args.optional(\"month\").isDefined, \"pass --date or --month\")","typeGuard":null,"tryCatchPattern":"try getDateRange(args) catch { case e: IllegalArgumentException if e.getMessage.startsWith(\"Adhoc\") => defaultLastWeek() }","preventionTips":["Add a wrapper script that refuses to launch without a window","Template adhoc commands with a placeholder date that must be filled","Document flag names in the job README"],"tags":["scala","scalding","date-range","cli-args"],"backgroundTag":"missing-required-parameter","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}