{"record":{"id":"5405924446c812bc","repo":"microsoft/qlib","slug":"unsupported-data-type-type-data","errorCode":null,"errorMessage":"Unsupported data type: {type(data)}.","messagePattern":"Unsupported data type: (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/torch.py","lineNumber":30,"sourceCode":"\n\ndef data_to_tensor(data, device=\"cpu\", raise_error=False):\n    if isinstance(data, torch.Tensor):\n        if device == \"cpu\":\n            return data.cpu()\n        else:\n            return data.to(device)\n    if isinstance(data, (pd.DataFrame, pd.Series)):\n        return data_to_tensor(torch.from_numpy(data.values).float(), device)\n    elif isinstance(data, np.ndarray):\n        return data_to_tensor(torch.from_numpy(data).float(), device)\n    elif isinstance(data, (tuple, list)):\n        return [data_to_tensor(i, device) for i in data]\n    elif isinstance(data, dict):\n        return {k: data_to_tensor(v, device) for k, v in data.items()}\n    else:\n        if raise_error:\n            raise ValueError(f\"Unsupported data type: {type(data)}.\")\n        else:\n            return data\n","sourceCodeStart":12,"sourceCodeEnd":33,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/torch.py#L12-L33","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Convert non-tensor leaves yourself before calling: wrap scalars with np.array(x, dtype=np.float32)","Call data_to_tensor(..., raise_error=False) so unsupported leaves pass through unchanged instead of raising","Strip string/datetime columns from the batch and keep only numeric arrays"],"exampleFix":"# before\nt = data_to_tensor({\"score\": scores, \"name\": names}, device)  # names are str -> raises\n\n# after\nt = data_to_tensor({\"score\": scores}, device)  # keep numeric leaves only","handlingStrategy":"type-guard","validationCode":"def tensorizable(data) -> bool:\n    import torch\n    if isinstance(data, (torch.Tensor, pd.DataFrame, pd.Series, np.ndarray)):\n        return True\n    if isinstance(data, (tuple, list)):\n        return all(tensorizable(i) for i in data)\n    if isinstance(data, dict):\n        return all(tensorizable(v) for v in data.values())\n    return False","typeGuard":"import torch, pandas as pd, numpy as np\n\ndef is_tensor_leaf(x) -> bool:\n    return isinstance(x, (torch.Tensor, pd.DataFrame, pd.Series, np.ndarray, int, float))","tryCatchPattern":"try:\n    batch = data_to_tensor(batch, device)\nexcept ValueError as e:\n    if 'Unsupported data type' in str(e):\n        batch = data_to_tensor(batch, device, raise_error=False)  # pass leaves through\n    else:\n        raise","preventionTips":["Keep batches numeric-only: strip string/datetime/None leaves before conversion","Use raise_error=False when batches legitimately contain non-tensor metadata","Wrap scalars as np.array(x, dtype=np.float32) if they must be converted"],"tags":["qlib","pytorch","tensor","type-error"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}