BerriAI/litellm · error · ValueError
start_time is required, got=
Error message
start_time is required, got={start_time} of type {type(start_time)} What it means
StandardLoggingPayloadSetup.cleanup_timestamps() normalizes a request's start/end/completion timestamps into epoch-second floats for the standard logging payload. It accepts only datetime.datetime instances or Python floats; every other type - None, str, int (time.time_ns(), int(time.time())), pandas.Timestamp, Decimal - raises this ValueError echoing the offending value and type. Note that Python ints fail even though they look numeric.
Solutions
- Pass epoch seconds as float: float(time.time()) instead of int or time.time_ns()
- Or pass datetime.datetime objects and let litellm call .timestamp() itself
- Or omit start_time entirely - litellm stamps it internally per request
- Coerce at the boundary: start_time = start_time.timestamp() if isinstance(start_time, datetime.datetime) else float(start_time)
Example fix
# before import time litellm.completion(model="gpt-4o", messages=m, start_time=time.time_ns()) # int -> ValueError # after import time litellm.completion(model="gpt-4o", messages=m, start_time=float(time.time())) # or: from datetime import datetime, timezone; start_time=datetime.now(timezone.utc)
Defensive patterns
Strategy: type-guard
Validate before calling
from datetime import datetime
def to_epoch_seconds(v):
if isinstance(v, datetime):
return v.timestamp()
if isinstance(v, float):
return v
if isinstance(v, int) and not isinstance(v, bool):
return float(v)
raise TypeError(f"unsupported timestamp: {v!r}")
litellm.completion(model="gpt-4o", messages=m, start_time=to_epoch_seconds(start)) Type guard
from datetime import datetime
def is_valid_timestamp(v: object) -> bool:
return (isinstance(v, datetime) or isinstance(v, float)) and not isinstance(v, bool) Try / catch
try:
litellm.completion(..., start_time=start)
except ValueError as e:
if "start_time is required" in str(e):
start = float(start) # or datetime.now(timezone.utc)
litellm.completion(..., start_time=start) Prevention
- Always pass datetime objects or float(time.time()); never ints or time.time_ns()
- Centralize timestamp creation in one helper so all call sites share the coercion
- Omit start_time when you have no explicit timing need - litellm stamps it itself
When it happens
Trigger: Passing start_time=time.time_ns() or int(time.time()) to litellm.completion/embedding, or a custom logger invoking StandardLoggingPayloadSetup.cleanup_timestamps with an ISO string, None, or other non-datetime/non-float value.
Common situations: Latency-test harnesses seeding nanosecond ints; timestamps loaded from JSON/DB as ISO-8601 strings and passed through; None leaking from conditionally computed timer values; pandas Timestamps from dataframe pipelines.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- end_time is required, got=
- usage is required, got=
- api base needs to be a string. api_base=
- 'argilla_transformation_object' must be a dictionary, to…
- completion_response must be of type ImageResponse for…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/7d014fd507e4c89f.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/litellm_core_utils/litellm_logging.py:4726
) -> tuple[float, float, float]:
"""
Convert datetime objects to floats
Args:
start_time: Union[dt_object, float]
end_time: Union[dt_object, float]
completion_start_time: Union[dt_object, float]
Returns:
Tuple[float, float, float]: A tuple containing the start time, end time, and completion start time as floats.
"""
if isinstance(start_time, datetime.datetime):
start_time_float = start_time.timestamp()
elif isinstance(start_time, float):
start_time_float = start_time
else:
raise ValueError(f"start_time is required, got={start_time} of type {type(start_time)}")
if isinstance(end_time, datetime.datetime):
end_time_float = end_time.timestamp()
elif isinstance(end_time, float):
end_time_float = end_time
else:
raise ValueError(f"end_time is required, got={end_time} of type {type(end_time)}")
if isinstance(completion_start_time, datetime.datetime):
completion_start_time_float = completion_start_time.timestamp()
elif isinstance(completion_start_time, float):
completion_start_time_float = completion_start_time
else:
completion_start_time_float = end_time_float
return start_time_float, end_time_float, completion_start_time_float
@staticmethodView on GitHub (pinned to 77b7c6c40c)