BerriAI/litellm · error · ValueError
Unsupported frequency: {self.frequency}
Error message
Unsupported frequency: {self.frequency} What it means
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.
Source
Thrown at litellm/integrations/focus/focus_logger.py:172
)
def _build_scheduler_trigger(self) -> dict[str, Any]:
"""Return scheduler configuration for the selected frequency."""
if self.frequency == "interval":
seconds: Final = self.interval_seconds or 60
return {"trigger": "interval", "seconds": seconds}
if self.frequency == "hourly":
minute = max(0, min(59, self.cron_offset_minute))
return {"trigger": "cron", "minute": minute, "second": 0}
if self.frequency == "daily":
total_minutes: Final = max(0, self.cron_offset_minute)
hour: Final = min(23, total_minutes // 60)
minute = min(59, total_minutes % 60)
return {"trigger": "cron", "hour": hour, "minute": minute, "second": 0}
raise ValueError(f"Unsupported frequency: {self.frequency}")
async def _run_scheduled_export(self) -> None:
"""Execute the scheduled export for the configured window."""
window: Final = self._compute_time_window(datetime.now(timezone.utc))
await self._export_window(window=window, limit=None)
async def _export_all(
self,
*,
limit: int | None,
) -> None:
"""Export all available data without a time window filter."""
engine: Final = self._ensure_engine()
await engine.export_all(limit=limit)
async def _export_window(
self,
*,View on GitHub (pinned to 6c2dcb801b)
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.
Example fix
# before FocusLogger(frequency="weekly") # after FocusLogger(frequency="daily")
Defensive patterns
Strategy: validation
Validate before calling
VALID = {"interval", "hourly", "daily"}
freq = (frequency or "").strip().lower()
if freq not in VALID:
raise ValueError(f"frequency must be one of {sorted(VALID)}, got {frequency!r}")
logger = FocusLogger(frequency=freq, ...) Type guard
FocusFrequency = Literal["interval", "hourly", "daily"]
def is_focus_frequency(v: object) -> bool:
return isinstance(v, str) and v in {"interval", "hourly", "daily"} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Case mismatch; a config value copied from cron shorthand; frequency defaulted to empty string by templating; version drift after a rename of supported values.
Related errors
- bucket_name must be provided for S3 destination
- Export format '{self.export_format}' not supported. Use 'par
- Event hook {hook} is not in the supported event hooks {suppo
- Event hook {event_hook} is not in the supported event hooks
- Invalid environment: {environment}. Please use one of the fo
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/cbe3bb12f437d812.
Report an issue: GitHub.