{"record":{"id":"5dccdfbfbf453379","repo":"BerriAI/litellm","slug":"input-must-be-a-string-or-a-list","errorCode":null,"errorMessage":"input must be a string or a list","messagePattern":"input must be a string or a list","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/caching/caching_handler.py","lineNumber":378,"sourceCode":"                        self.preset_cache_key\n                        or self.request_kwargs.get(\"cache_key\")\n                        or litellm.cache.get_cache_key(**self.request_kwargs)\n                    )\n                    if hasattr(cached_result, \"_hidden_params\"):\n                        cached_result._hidden_params[\"cache_key\"] = cache_key\n                    return CachingHandlerResponse(cached_result=cached_result)\n        return CachingHandlerResponse(cached_result=cached_result)\n\n    def handle_kwargs_input_list_or_str(self, kwargs: dict[str, Any]) -> list[str]:\n        \"\"\"\n        Handles the input of kwargs['input'] being a list or a string\n        \"\"\"\n        if isinstance(kwargs[\"input\"], str):\n            return [kwargs[\"input\"]]\n        elif isinstance(kwargs[\"input\"], list):\n            return kwargs[\"input\"]\n        else:\n            raise ValueError(\"input must be a string or a list\")\n\n    def _extract_model_from_cached_results(self, non_null_list: list[tuple[int, CachedEmbedding]]) -> str | None:\n        \"\"\"\n        Helper method to extract the model name from cached results.\n\n        Args:\n            non_null_list: List of (idx, cr) tuples where cr is the cached result dict\n\n        Returns:\n            Optional[str]: The model name if found, None otherwise\n        \"\"\"\n        for _, cr in non_null_list:\n            if isinstance(cr, dict) and cr.get(\"model\"):\n                return cr[\"model\"]\n        return None\n\n    def _process_async_embedding_cached_response(\n        self,","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/caching/caching_handler.py#L360-L396","documentation":"ValueError from CachingHandler.handle_kwargs_input_list_or_str: kwargs['input'] is neither a str nor a list. LiteLLM's embedding cache layer normalizes input by wrapping a string into a one-element list and passing lists through; any other type (None, int, dict) fails the isinstance chain and is rejected.","triggerScenarios":"Calling litellm.embedding (or aembedding) with caching enabled where input is not a string or list — e.g. input=None, input=12345 (token ids as a plain int, not wrapped in a list), or a numpy array/tensor passed directly.","commonSituations":"Passing token-id arrays (list-of-ints is fine, but a bare numpy array/torch tensor is not); a None default leaking from upstream config; passing bytes or other exotic payload types.","solutions":["Convert before calling: wrap strings as-is, convert arrays with input=list(arr), and ensure input is never None.","For token ids, pass a list of ints (list[list[int]] for multiple inputs).","Add a type check at your call site for data sourced from users/pipelines."],"exampleFix":"# before\nlitellm.embedding(model=\"text-embedding-3-small\", input=np.array([1,2,3]))\n\n# after\nlitellm.embedding(model=\"text-embedding-3-small\", input=list(np.array([1,2,3])))","handlingStrategy":"type-guard","validationCode":"if not isinstance(user_input, (str, list)):\n    user_input = list(user_input) if hasattr(user_input, \"__iter__\") else [user_input]","typeGuard":"def is_valid_embedding_input(v) -> bool:\n    return isinstance(v, (str, list))","tryCatchPattern":null,"preventionTips":["Normalize all embedding inputs through one helper that enforces str|list.","Reject None and exotic types at the API boundary of your service.","Convert numpy/torch arrays with .tolist() before calling LiteLLM."],"tags":["caching","embeddings","type-validation","python"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}