mlflow/mlflow · error · ValueError

Unsupported data type.

Error message

Unsupported data type.

What it means

MLflow computes an MD5 digest of evaluation datasets by hashing array-like inputs (pandas DataFrames, numpy arrays, or lists). If the data object passed to the internal hashing helper is none of these supported types, a plain ValueError('Unsupported data type.') is raised from _hash_array_like_obj_as_bytes.

Source

Thrown at mlflow/data/evaluation_dataset.py:155

        else:
            data = data.applymap(_hash_array_like_element_as_bytes)
        return _hash_uint64_ndarray_as_bytes(pd.util.hash_pandas_object(data))
    elif isinstance(data, np.ndarray) and len(data) > 0 and isinstance(data[0], list):
        # convert numpy array of lists into numpy array of the string representation of the lists
        # because lists are not hashable
        hashable = np.array(str(val) for val in data)
        return _hash_ndarray_as_bytes(hashable)
    elif isinstance(data, np.ndarray) and len(data) > 0 and isinstance(data[0], np.ndarray):
        # convert numpy array of numpy arrays into 2d numpy arrays
        # because numpy array of numpy arrays are not hashable
        hashable = np.array(data.tolist())
        return _hash_ndarray_as_bytes(hashable)
    elif isinstance(data, np.ndarray):
        return _hash_ndarray_as_bytes(data)
    elif isinstance(data, list):
        return _hash_ndarray_as_bytes(np.array(data))
    else:
        raise ValueError("Unsupported data type.")


def _gen_md5_for_arraylike_obj(md5_gen, data):
    """
    Helper method to generate MD5 hash array-like object, the MD5 will calculate over:
     - array length
     - first NUM_SAMPLE_ROWS_FOR_HASH rows content
     - last NUM_SAMPLE_ROWS_FOR_HASH rows content
    """
    len_bytes = _hash_uint64_ndarray_as_bytes(np.array([len(data)], dtype="uint64"))
    md5_gen.update(len_bytes)
    if len(data) < EvaluationDataset.NUM_SAMPLE_ROWS_FOR_HASH * 2:
        md5_gen.update(_hash_array_like_obj_as_bytes(data))
    else:
        if isinstance(data, pd.DataFrame):
            # Access rows of pandas Df with iloc
            head_rows = data.iloc[: EvaluationDataset.NUM_SAMPLE_ROWS_FOR_HASH]
            tail_rows = data.iloc[-EvaluationDataset.NUM_SAMPLE_ROWS_FOR_HASH :]

View on GitHub (pinned to 6a27f2decc)

Solutions

  1. Convert the input to a supported type: np.asarray(obj) for arrays/targets or pd.DataFrame(obj) for tabular data before calling evaluate().
  2. If data is a list of lists, make all elements the same length so np.array(data) succeeds.
  3. Check types at the call site with isinstance(data, (np.ndarray, list, pd.DataFrame)) and handle the else branch explicitly.
  4. For non-numeric containers like list of dicts, build a DataFrame with pd.json_normalize first.

Example fix

// before
mlflow.models.evaluate(model, data=X_tuple, targets=y_series)
// after
import numpy as np
mlflow.models.evaluate(
    model,
    data=np.asarray(X_tuple),
    targets=np.asarray(y_series),
)
Defensive patterns

Strategy: type-guard

Validate before calling

def check_hashable_input(data, targets=None):
    import pandas as pd, numpy as np
    ok = lambda o: isinstance(o, (pd.DataFrame, np.ndarray, list))
    if not ok(data):
        raise TypeError(f"data must be DataFrame/ndarray/list, got {type(data)}")
    if targets is not None and not ok(targets):
        raise TypeError(f"targets must be DataFrame/ndarray/list, got {type(targets)}")

Type guard

function isSupportedArrayLike(x) { return x instanceof pd.DataFrame || x instanceof np.ndarray || Array.isArray(x); }

Try / catch

try:
    mlflow.models.evaluate(model, data=data, targets=targets)
except ValueError as e:
    if "Unsupported data type" in str(e):
        data, targets = np.asarray(data), np.asarray(targets)
        mlflow.models.evaluate(model, data=data, targets=targets)
    else:
        raise

Prevention

When it happens

Trigger: Calling mlflow.models.evaluate() (or creating an EvaluationDataset whose digest must be computed) with data/targets that is not a pandas DataFrame, numpy ndarray, or list — e.g. a dict, tuple, pandas Series, list of dicts, ragged list, or numpy object array whose conversion to np.array fails or yields an unsupported type.

Common situations: Passing a pandas Series or a dict as targets; passing a list of unequal-length lists (np.array raises inside); using sparse/scipy arrays; forgetting to convert a loader's output (e.g. sklearn Bunch, torch tensor) to numpy before evaluate().

Related errors


AI-assisted analysis of mlflow/mlflow@6a27f2decc (2026-08-29). Data as JSON: /api/errors/89ba939a4c5a0d9a. Report an issue: GitHub.