{"record":{"id":"11cd5fc283a7326a","repo":"BerriAI/litellm","slug":"either-text-or-messages-must-be-provided","errorCode":null,"errorMessage":"Either text or messages must be provided","messagePattern":"Either text or messages must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/token_counter.py","lineNumber":398,"sourceCode":"        if tools or tool_choice:\n            raise ValueError(\"tools or tool_choice cannot be set if using text\")\n        if isinstance(text, list):\n            text_to_count = \"\".join(t for t in text if isinstance(t, str))\n        elif isinstance(text, str):\n            text_to_count = text\n        count_function: Final = _get_count_function(model, custom_tokenizer)\n        num_tokens = count_function(text_to_count)\n\n    elif messages is not None:\n        new_messages: Final = cast(list[AllMessageValues], convert_list_message_to_dict(messages))\n        params: Final = _MessageCountParams(model, custom_tokenizer)\n        num_tokens = _count_messages(params, new_messages, use_default_image_token_count, default_token_count)\n        if count_response_tokens is False:\n            includes_system_message: Final = any([message.get(\"role\", None) == \"system\" for message in new_messages])\n            num_tokens += _count_extra(params.count_function, tools, tool_choice, includes_system_message)\n\n    else:\n        raise ValueError(\"Either text or messages must be provided\")\n\n    return num_tokens\n\n\ndef _count_function_call_tokens(\n    key: str,\n    value: Any,\n    message: Mapping[str, Any],\n    count_function: TokenCounterFunction,\n) -> int:\n    \"\"\"\n    Count tokens contributed by an assistant message's tool/function call payload.\n\n    Handles both the modern `tool_calls` list and the legacy OpenAI\n    `function_call` dict. Only the `arguments` string is counted (matching the\n    existing tool_calls behavior); names are accounted for elsewhere via the\n    tool/function definitions and `tool_choice`.\n    \"\"\"","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/token_counter.py#L380-L416","documentation":"token_counter() received neither text= nor messages=, so there is nothing to count. This fires when both arguments are None (including explicitly passing None), and litellm.disable_token_counter is not set. It is a fail-fast guard against silently returning 0 for a no-op call.","triggerScenarios":"token_counter(model=\"gpt-4o\") or token_counter(model=m, text=None, messages=None) - typically a wrapper whose payload computation failed on both branches, or variables that are None due to upstream bugs.","commonSituations":"Calling token_counter on optional fields (e.g. message.get(\"content\")) that are None; refactors renaming the messages variable; counting an assistant reply that has no content.","solutions":["Check the argument before calling: only invoke when text or messages is truthy.","Fix the upstream variable that is unexpectedly None (log it) rather than defaulting blindly.","If empty inputs are expected, guard at the call site: return 0 when both are absent."],"exampleFix":"# before\nn = litellm.token_counter(model=m, text=msg.get(\"content\"))  # content is None -> raises\n\n# after\ncontent = msg.get(\"content\")\nn = litellm.token_counter(model=m, text=content) if isinstance(content, str) else 0","handlingStrategy":"type-guard","validationCode":"if not text and not messages:\n    return 0  # nothing to count\nreturn litellm.token_counter(model=model, text=text, messages=messages)","typeGuard":"def has_countable_payload(text, messages) -> bool:\n    return bool(text) or bool(messages)","tryCatchPattern":null,"preventionTips":["Log inputs to token counting in debug builds to catch silent None payloads.","Guard optional fields (message.get('content')) before counting."],"tags":["token-counter","validation","null-handling"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}