{"record":{"id":"2a4d1fa346ce26e4","repo":"mlflow/mlflow","slug":"unsupported-input-type-type-data-it-must-be-o","errorCode":null,"errorMessage":"Unsupported input type: {type(data)}. It must be one of [str, dict, list, numpy.ndarray, pandas.DataFrame]","messagePattern":"Unsupported input type: (.+?)\\. It must be one of \\[str, dict, list, numpy\\.ndarray, pandas\\.DataFrame\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mlflow/llama_index/pyfunc_wrapper.py","lineNumber":53,"sourceCode":"    return data\n\n\ndef _format_predict_input_query_engine_and_retriever(data) -> \"QueryBundle\":\n    \"\"\"Convert pyfunc input to a QueryBundle.\"\"\"\n    from llama_index.core import QueryBundle\n\n    data = _convert_llm_input_data_with_unwrapping(data)\n\n    if isinstance(data, str):\n        return QueryBundle(query_str=data)\n    elif isinstance(data, dict):\n        return QueryBundle(**data)\n    elif isinstance(data, list):\n        # NB: handle pandas returning lists when there is a single row\n        prediction_input = [_format_predict_input_query_engine_and_retriever(d) for d in data]\n        return prediction_input if len(prediction_input) > 1 else prediction_input[0]\n    else:\n        raise ValueError(\n            f\"Unsupported input type: {type(data)}. It must be one of \"\n            \"[str, dict, list, numpy.ndarray, pandas.DataFrame]\"\n        )\n\n\nclass _LlamaIndexModelWrapperBase:\n    def __init__(\n        self,\n        llama_model,  # Engine or Workflow\n        model_config: dict[str, Any] | None = None,\n    ):\n        self._llama_model = llama_model\n        self.model_config = model_config or {}\n\n    @property\n    def index(self):\n        return self._llama_model.index\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/mlflow/mlflow/blob/6a27f2decc0b76eb1b54af31849784addb357dbc/mlflow/llama_index/pyfunc_wrapper.py#L35-L71","documentation":"When the saved model is a query engine or retriever, MLflow's pyfunc wrapper converts predict() input into a llama_index QueryBundle. Only str, dict, list, numpy.ndarray, and pandas.DataFrame inputs are recognized; anything else falls through to the final else and raises ValueError.","triggerScenarios":"Calling model.predict(x) (or pyfunc.predict) on a QueryEngineWrapper/RetrieverEngineWrapper with an unsupported type such as a tuple, set, torch.Tensor, scipy sparse matrix, PIL image, or a custom object.","commonSituations":"Passing a tuple instead of a list; passing a Dataset/dataloader batch tensor instead of converting to numpy first; a DataFrame column (pandas Series) rather than a full DataFrame; calling model.predict on multiple items in a Python tuple from an earlier pipeline step.","solutions":["Coerce the input to one of the supported types: str for a plain query, dict for structured query fields (query_str etc.), list of any of these, numpy.ndarray, or pandas.DataFrame.","For a tensor, call x.detach().cpu().numpy() before predict().","For a Series, wrap with pd.DataFrame(series) or convert to a list.","If you're batching queries, pass a list of strings or a DataFrame with one query per row.","If you need richer input, construct a dict whose keys match QueryBundle fields (e.g. {\"query_str\": \"...\"})."],"exampleFix":"// before\nimport numpy as np\npred = model.predict((\"query one\", \"query two\"))  # tuple, not list\n// after\npred = model.predict([\"query one\", \"query two\"])","handlingStrategy":"type-guard","validationCode":"import numpy as np\nimport pandas as pd\nALLOWED = (str, dict, list, np.ndarray, pd.DataFrame)\nif not isinstance(data, ALLOWED):\n    data = _coerce(data)  # e.g. tuple->list, tensor->numpy","typeGuard":"from typing import Any\nimport numpy as np\nimport pandas as pd\ndef is_valid_query_input(x: Any) -> bool:\n    return isinstance(x, (str, dict, list, np.ndarray, pd.DataFrame))","tryCatchPattern":"try:\n    return model.predict(data)\nexcept ValueError as e:\n    if str(e).startswith(\"Unsupported input type\"):\n        data = coerce_input(data)\n        return model.predict(data)\n    raise","preventionTips":["Convert tensors/tuples/sets to numpy/list before predict.","Keep batching inputs as list or DataFrame.","Document the accepted input types next to your inference code.","Add an assert with the allowlist in your serving layer."],"tags":["mlflow","llama-index","pyfunc","input-validation"],"backgroundTag":"unsupported-input-type","analyzedSha":"6a27f2decc0b76eb1b54af31849784addb357dbc","analyzedAt":"2026-08-29T20:54:51.419Z","schemaVersion":2},"datasetVersion":"2026-08-29T22:17:34.462Z"}