{"record":{"id":"08aa466e53704ab6","repo":"BerriAI/litellm","slug":"end-time-is-required-got-end-time-of-type-type","errorCode":null,"errorMessage":"end_time is required, got={end_time} of type {type(end_time)}","messagePattern":"end_time is required, got=(.+?) of type (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/litellm_logging.py","lineNumber":4733,"sourceCode":"            completion_start_time: Union[dt_object, float]\n\n        Returns:\n            Tuple[float, float, float]: A tuple containing the start time, end time, and completion start time as floats.\n        \"\"\"\n\n        if isinstance(start_time, datetime.datetime):\n            start_time_float = start_time.timestamp()\n        elif isinstance(start_time, float):\n            start_time_float = start_time\n        else:\n            raise ValueError(f\"start_time is required, got={start_time} of type {type(start_time)}\")\n\n        if isinstance(end_time, datetime.datetime):\n            end_time_float = end_time.timestamp()\n        elif isinstance(end_time, float):\n            end_time_float = end_time\n        else:\n            raise ValueError(f\"end_time is required, got={end_time} of type {type(end_time)}\")\n\n        if isinstance(completion_start_time, datetime.datetime):\n            completion_start_time_float = completion_start_time.timestamp()\n        elif isinstance(completion_start_time, float):\n            completion_start_time_float = completion_start_time\n        else:\n            completion_start_time_float = end_time_float\n\n        return start_time_float, end_time_float, completion_start_time_float\n\n    @staticmethod\n    def append_system_prompt_messages(kwargs: dict | None = None, messages: Any | None = None):\n        \"\"\"\n        Append system prompt messages to the messages\n        \"\"\"\n        if kwargs is not None:\n            if kwargs.get(\"system\") is not None and isinstance(kwargs.get(\"system\"), str):\n                if messages is None:","sourceCodeStart":4715,"sourceCodeEnd":4751,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/litellm_core_utils/litellm_logging.py#L4715-L4751","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()"],"exampleFix":"# before\nstart, end = int(time.time()), int(time.time()) + 2\nlitellm.completion(model=\"gpt-4o\", messages=m, start_time=start, end_time=end)  # ValueError on end_time\n\n# after\nstart, end = time.time(), time.time() + 2  # floats\nlitellm.completion(model=\"gpt-4o\", messages=m, start_time=start, end_time=end)","handlingStrategy":"type-guard","validationCode":"from datetime import datetime\n\nif end_time is not None and not isinstance(end_time, (datetime, float)):\n    end_time = float(end_time)  # coerce ints; strings should fail loudly in your code first\nlitellm.completion(model=\"gpt-4o\", messages=m, end_time=end_time)","typeGuard":"from datetime import datetime\n\ndef is_valid_timestamp(v: object) -> bool:\n    return (isinstance(v, datetime) or isinstance(v, float)) and not isinstance(v, bool)","tryCatchPattern":"try:\n    litellm.completion(..., end_time=end)\nexcept ValueError as e:\n    if \"end_time is required\" in str(e):\n        end = float(end)\n        litellm.completion(..., end_time=end)","preventionTips":["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"],"tags":["litellm","logging","type-validation","timestamps"],"backgroundTag":"invalid-argument-value","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}