BerriAI/litellm · error · ValueError
Invalid budget_reset_time {raw!r}; must be a quoted 24-hour
Error message
Invalid budget_reset_time {raw!r}; must be a quoted 24-hour 'HH:MM' string, e.g. "12:00" What it means
ValueError from parse_budget_reset_time in litellm/proxy/common_utils/timezone_utils.py when the budget_reset_time config value is present but is not a string. The parser deliberately fails loudly at startup instead of silently resetting budgets at midnight. Non-string values almost always come from YAML type coercion (e.g. an unquoted 12:00 in YAML 1.1 is parsed as a sexagesimal integer) or from passing a datetime.time object where a quoted string is expected.
Source
Thrown at litellm/proxy/common_utils/timezone_utils.py:32
module-level globals at call time.
"""
model_config = ConfigDict(frozen=True)
timezone: str = "UTC"
reset_time_of_day: time = time(0, 0)
def parse_budget_reset_time(raw: object) -> time:
"""Parse a `budget_reset_time` config value (e.g. "12:00") into a `time`.
Falls back to midnight when unset; raises a clear error on a malformed value
so a bad config fails loudly at startup instead of silently resetting at midnight.
"""
if raw is None or raw == "":
return time(0, 0)
if not isinstance(raw, str):
raise ValueError(f"Invalid budget_reset_time {raw!r}; must be a quoted 24-hour 'HH:MM' string, e.g. \"12:00\"")
for fmt in ("%H:%M", "%H:%M:%S"):
try:
parsed = datetime.strptime(raw, fmt)
return time(hour=parsed.hour, minute=parsed.minute, second=parsed.second)
except ValueError:
continue
raise ValueError(
f"Invalid budget_reset_time {raw!r}; expected a 24-hour 'HH:MM' or 'HH:MM:SS' string, e.g. \"12:00\""
)
def get_budget_reset_timezone() -> str:
"""
Get the budget reset timezone from litellm_settings.
Falls back to UTC if not specified.
litellm_settings values are set as attributes on the litellm module
by proxy_server.py at startup (via setattr(litellm, key, value)).View on GitHub (pinned to 77b7c6c40c)
Solutions
- Quote the value in YAML: budget_reset_time: "12:00".
- If building the config in Python, serialize with .strftime('%H:%M') or .isoformat() before dumping to YAML.
- Remove the budget_reset_time key entirely if midnight (00:00) is acceptable — None and empty string both fall back to midnight without erroring.
Example fix
# before (YAML 1.1 parses 12:00 as int 720 -> ValueError) budget_reset_time: 12:00 # after budget_reset_time: "12:00"
Defensive patterns
Strategy: validation
Validate before calling
from datetime import time
def validate_budget_reset_time(raw) -> time:
if raw is None or raw == "":
return time(0, 0)
if not isinstance(raw, str):
raise TypeError("budget_reset_time must be a quoted string like '12:00'")
return raw # string ok, format checked separately Type guard
def is_valid_budget_reset_time_value(raw: object) -> bool:
return raw is None or raw == "" or (isinstance(raw, str) and len(raw) >= 4 and raw[2] == ":") Try / catch
try:
from litellm.proxy.common_utils.timezone_utils import parse_budget_reset_time
reset_at = parse_budget_reset_time(cfg.get("budget_reset_time"))
except ValueError as e:
raise SystemConfigError(f"bad budget_reset_time: {e}") from e Prevention
- Always quote HH:MM values in YAML configs ('budget_reset_time: "12:00"').
- When generating configs from Python, strftime('%H:%M') before yaml.dump.
- Lint proxy configs in CI with a schema that types budget_reset_time as string-pattern '^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$'.
When it happens
Trigger: Setting budget_reset_time: 12:00 unquoted in proxy_config.yaml (PyYAML parses it as the int 720, not the string '12:00'); passing budget_reset_time as a datetime.time object programmatically; passing a number (budget_reset_time: 0) or any non-string YAML scalar to a virtual key budget config.
Common situations: Copying an example config that shows budget_reset_time: 12:00 without quotes; upgrading LiteLLM to a version that added strict validation where previously the value was ignored; generating config programmatically with yaml.dump of a time object.
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- mcp_tools_config must be a list of dictionaries
- Invalid budget_reset_time {raw!r}; expected a 24-hour 'HH:MM
- Custom code guardrail requires a guardrail_name
- Custom code guardrail requires 'custom_code' in litellm_para
- max_budget cannot be negative. Received: {data.max_budget}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/8b4c80c4377a8146.
Report an issue: GitHub.