BerriAI/litellm · error · ValueError

Unsupported duration unit, passed duration: {duration}

Error message

Unsupported duration unit, passed duration: {duration}

What it means

The terminal else of the duration-to-seconds logic: the value/unit pair was extracted, but the unit is not one of the supported set ('', 's', 'm', 'h', 'd', 'w', 'mo'), so the code cannot compute a duration and raises ValueError including the original string. Note the leading-digits regex is not end-anchored, so trailing junk usually surfaces here rather than at error 571.

Source

Thrown at litellm/litellm_core_utils/duration_parser.py:106

        target_day = min(target_day, last_day_of_target_month)

        next_month: Final = datetime(
            year=target_year,
            month=target_month,
            day=target_day,
            hour=current_time.hour,
            minute=current_time.minute,
            second=current_time.second,
            microsecond=current_time.microsecond,
        )

        # Calculate the duration until the first day of the next month
        duration_until_next_month: Final = next_month - current_time
        return int(duration_until_next_month.total_seconds())

    else:
        raise ValueError(f"Unsupported duration unit, passed duration: {duration}")


def get_next_standardized_reset_time(
    duration: str,
    current_time: datetime,
    timezone_str: str = "UTC",
    reset_time_of_day: time = time(0, 0),
) -> datetime:
    """
    Get the next standardized reset time based on the duration.

    All durations will reset at predictable intervals, aligned from the current time:
    - Nd: If N=1, reset at the next `reset_time_of_day`; if N>1, reset every N days from now
    - Nh: Every N hours, aligned to hour boundaries (e.g., 1:00, 2:00)
    - Nm: Every N minutes, aligned to minute boundaries (e.g., 1:05, 1:10)
    - Ns: Every N seconds, aligned to second boundaries

    Parameters:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Convert to supported units: '1y' -> '365d' (or '12mo' only where 1-month resets apply), '1hr' -> '1h', '30sec' -> '30s'.
  2. Compound durations must be split and summed as separate supported values, or precomputed to plain seconds ('25h' -> '90000').
  3. Add a unit whitelist check in your config pipeline so unsupported units fail at deploy time with a clear message.

Example fix

# before
budget_duration="1y"     # 'y' is not a supported unit

# after
budget_duration="365d"   # express years in days
# or seconds directly: "31536000"
Defensive patterns

Strategy: validation

Validate before calling

import re

SUPPORTED_UNITS = {"", "s", "m", "h", "d", "w", "mo"}

def is_supported_duration(v: str) -> bool:
    m = re.match(r"^(\d+)(mo|[smhdw]?)$", v.strip())
    return bool(m) and m.group(2) in SUPPORTED_UNITS

assert not is_supported_duration("1y")
assert is_supported_duration("365d")

Type guard

def has_supported_unit(v: object) -> bool:
    if not isinstance(v, str):
        return False
    m = re.match(r"^(\d+)(mo|[smhdw]?)$", v.strip())
    return bool(m) and m.group(2) in {"", "s", "m", "h", "d", "w", "mo"}

Try / catch

from litellm.litellm_core_utils.duration_parser import get_duration
try:
    seconds = get_duration(duration)
except ValueError as e:
    if "Unsupported duration unit" in str(e):
        duration = convert_to_supported(duration)  # '1y'->'365d', '1hr'->'1h'
        seconds = get_duration(duration)
    else:
        raise

Prevention

When it happens

Trigger: Durations like '1y' (year — unsupported), '1x', '30sec' or '1d12h' (the match grabs '1d' or unit-less digits but subsequent parsing of leftovers fails / unit unknown), '0.5d'. Basically any integer+letter combination whose unit is not in {s,m,h,d,w,mo} or any string with text after a valid prefix that the downstream switch cannot handle.

Common situations: Users naturally writing '1y' for annual budgets or '1hr'; copy-pasted ISO-8601 ('P1D') or cron-ish values; config generated by templating that appends units litellm does not know.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/2ee6b5e953b50c42. Report an issue: GitHub.