BerriAI/litellm · error · ValueError
end_time is required, got=
Error message
end_time is required, got={end_time} of type {type(end_time)} What it means
Same normalizer as the start_time check: StandardLoggingPayloadSetup.cleanup_timestamps() converts end_time (and completion_start_time) to epoch-second floats and accepts only datetime.datetime or float. Any other type for end_time - None, str, int such as int(time.time()) - raises this ValueError with the value and its type. completion_start_time alone is forgiving: invalid types fall back to end_time_float.
Solutions
- Pass float(time.time()) or a datetime.datetime for end_time
- Compute end_time unconditionally before the call (guard the None-on-early-exit path)
- Omit end_time and let litellm set it when the response returns
- Coerce at the boundary: end_time = float(end_time) if isinstance(end_time, (int, float)) and not isinstance(end_time, bool) else end_time.timestamp()
Example fix
# before start, end = int(time.time()), int(time.time()) + 2 litellm.completion(model="gpt-4o", messages=m, start_time=start, end_time=end) # ValueError on end_time # after start, end = time.time(), time.time() + 2 # floats litellm.completion(model="gpt-4o", messages=m, start_time=start, end_time=end)
Defensive patterns
Strategy: type-guard
Validate before calling
from datetime import datetime
if end_time is not None and not isinstance(end_time, (datetime, float)):
end_time = float(end_time) # coerce ints; strings should fail loudly in your code first
litellm.completion(model="gpt-4o", messages=m, end_time=end_time) 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(..., end_time=end)
except ValueError as e:
if "end_time is required" in str(e):
end = float(end)
litellm.completion(..., end_time=end) Prevention
- Use one timer utility that returns floats for both start and end
- Ensure end_time is computed on every code path (no None on early exit)
- Prefer omitting end_time over passing a possibly-wrong type
When it happens
Trigger: Calling litellm completion/embedding (or the logging payload setup) with end_time=int(time.time()), an ISO string, or None - e.g. a custom timer that never fired, or time.time_ns() used for the finish timestamp.
Common situations: Symmetric latency measurement code that casts both times to int; end_time computed conditionally and left None on early exits; serialized timestamps re-read as strings from queues/caches.
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
- start_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/08aa466e53704ab6.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/litellm_core_utils/litellm_logging.py:4733
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
@staticmethod
def append_system_prompt_messages(kwargs: dict | None = None, messages: Any | None = None):
"""
Append system prompt messages to the messages
"""
if kwargs is not None:
if kwargs.get("system") is not None and isinstance(kwargs.get("system"), str):
if messages is None:View on GitHub (pinned to 77b7c6c40c)