{"record":{"id":"cbe3bb12f437d812","repo":"BerriAI/litellm","slug":"unsupported-frequency-self-frequency","errorCode":null,"errorMessage":"Unsupported frequency: {self.frequency}","messagePattern":"Unsupported frequency: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/focus/focus_logger.py","lineNumber":172,"sourceCode":"        )\n\n    def _build_scheduler_trigger(self) -> dict[str, Any]:\n        \"\"\"Return scheduler configuration for the selected frequency.\"\"\"\n        if self.frequency == \"interval\":\n            seconds: Final = self.interval_seconds or 60\n            return {\"trigger\": \"interval\", \"seconds\": seconds}\n\n        if self.frequency == \"hourly\":\n            minute = max(0, min(59, self.cron_offset_minute))\n            return {\"trigger\": \"cron\", \"minute\": minute, \"second\": 0}\n\n        if self.frequency == \"daily\":\n            total_minutes: Final = max(0, self.cron_offset_minute)\n            hour: Final = min(23, total_minutes // 60)\n            minute = min(59, total_minutes % 60)\n            return {\"trigger\": \"cron\", \"hour\": hour, \"minute\": minute, \"second\": 0}\n\n        raise ValueError(f\"Unsupported frequency: {self.frequency}\")\n\n    async def _run_scheduled_export(self) -> None:\n        \"\"\"Execute the scheduled export for the configured window.\"\"\"\n        window: Final = self._compute_time_window(datetime.now(timezone.utc))\n        await self._export_window(window=window, limit=None)\n\n    async def _export_all(\n        self,\n        *,\n        limit: int | None,\n    ) -> None:\n        \"\"\"Export all available data without a time window filter.\"\"\"\n        engine: Final = self._ensure_engine()\n        await engine.export_all(limit=limit)\n\n    async def _export_window(\n        self,\n        *,","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/focus/focus_logger.py#L154-L190","documentation":"FocusLogger raises ValueError when building the APScheduler trigger if self.frequency is not one of 'interval', 'hourly', 'daily'. The frequency string selects the trigger shape (interval seconds / hourly cron at cron_offset_minute / daily cron derived from cron_offset_minute); anything else falls through to this raise.","triggerScenarios":"Constructing FocusLogger(frequency='weekly'|'minute'|'HOURLY'|None) — any string other than the three supported lowercase values reaches the raise when the scheduler trigger dict is built.","commonSituations":"Case mismatch; a config value copied from cron shorthand; frequency defaulted to empty string by templating; version drift after a rename of supported values.","solutions":["Use exactly one of 'interval', 'hourly', 'daily' (lowercase).","Validate the value at config load time and fail fast with a clear message listing valid options.","For 'interval', also set interval_seconds."],"exampleFix":"# before\nFocusLogger(frequency=\"weekly\")\n\n# after\nFocusLogger(frequency=\"daily\")","handlingStrategy":"validation","validationCode":"VALID = {\"interval\", \"hourly\", \"daily\"}\nfreq = (frequency or \"\").strip().lower()\nif freq not in VALID:\n    raise ValueError(f\"frequency must be one of {sorted(VALID)}, got {frequency!r}\")\nlogger = FocusLogger(frequency=freq, ...)","typeGuard":"FocusFrequency = Literal[\"interval\", \"hourly\", \"daily\"]\n\ndef is_focus_frequency(v: object) -> bool:\n    return isinstance(v, str) and v in {\"interval\", \"hourly\", \"daily\"}","tryCatchPattern":null,"preventionTips":["Constrain frequency with an enum/Literal in config parsing.","Fail at startup with the list of valid values instead of at scheduler-build time.","Cover all three frequencies in config tests."],"tags":["config","focus-export","scheduler","validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}