microsoft/qlib · error · ValueError

Unsupported data type: {type(data)}.

Error message

Unsupported data type: {type(data)}.

What it means

data_to_tensor (qlib/contrib/torch.py) recursively converts nested Python structures (tensors, DataFrames, Series, ndarrays, tuples, lists, dicts) to torch tensors on a target device. When it meets a leaf of any other type and raise_error=True, it raises ValueError('Unsupported data type: ...'); with raise_error=False the leaf is passed through untouched.

Source

Thrown at qlib/contrib/torch.py:30


def data_to_tensor(data, device="cpu", raise_error=False):
    if isinstance(data, torch.Tensor):
        if device == "cpu":
            return data.cpu()
        else:
            return data.to(device)
    if isinstance(data, (pd.DataFrame, pd.Series)):
        return data_to_tensor(torch.from_numpy(data.values).float(), device)
    elif isinstance(data, np.ndarray):
        return data_to_tensor(torch.from_numpy(data).float(), device)
    elif isinstance(data, (tuple, list)):
        return [data_to_tensor(i, device) for i in data]
    elif isinstance(data, dict):
        return {k: data_to_tensor(v, device) for k, v in data.items()}
    else:
        if raise_error:
            raise ValueError(f"Unsupported data type: {type(data)}.")
        else:
            return data

View on GitHub (pinned to 79633dd950)

Solutions

  1. Convert non-tensor leaves yourself before calling: wrap scalars with np.array(x, dtype=np.float32)
  2. Call data_to_tensor(..., raise_error=False) so unsupported leaves pass through unchanged instead of raising
  3. Strip string/datetime columns from the batch and keep only numeric arrays

Example fix

# before
t = data_to_tensor({"score": scores, "name": names}, device)  # names are str -> raises

# after
t = data_to_tensor({"score": scores}, device)  # keep numeric leaves only
Defensive patterns

Strategy: type-guard

Validate before calling

def tensorizable(data) -> bool:
    import torch
    if isinstance(data, (torch.Tensor, pd.DataFrame, pd.Series, np.ndarray)):
        return True
    if isinstance(data, (tuple, list)):
        return all(tensorizable(i) for i in data)
    if isinstance(data, dict):
        return all(tensorizable(v) for v in data.values())
    return False

Type guard

import torch, pandas as pd, numpy as np

def is_tensor_leaf(x) -> bool:
    return isinstance(x, (torch.Tensor, pd.DataFrame, pd.Series, np.ndarray, int, float))

Try / catch

try:
    batch = data_to_tensor(batch, device)
except ValueError as e:
    if 'Unsupported data type' in str(e):
        batch = data_to_tensor(batch, device, raise_error=False)  # pass leaves through
    else:
        raise

Prevention

When it happens

Trigger: Calling data_to_tensor(data, device) (directly or via a Torch model's dataset-to-device path) with data containing scalars, strings, None, or custom objects nested inside, and raise_error=True (the default in some call paths).

Common situations: Batch data containing non-numeric fields (stock_id strings, datetime columns, NaN-free scalar labels), custom dataset __getitem__ returning heterogeneous tuples, or None placeholder values in sampled batches.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/5405924446c812bc. Report an issue: GitHub.