{"record":{"id":"235dacd106155a34","repo":"sgl-project/sglang","slug":"input-data-must-be-a-torch-tensor-but-got-type","errorCode":null,"errorMessage":"Input 'data' must be a torch.Tensor, but got {type(data)}","messagePattern":"Input 'data' must be a torch\\.Tensor, but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/managers/mm_utils.py","lineNumber":132,"sourceCode":"class TransportProxyTensor(torch.Tensor):\n    \"\"\"\n    A convenient torch.Tensor subclass that carries extra metadata and supports\n    efficient inter-process communications\n    \"\"\"\n\n    @staticmethod\n    def __new__(\n        cls,\n        data: torch.Tensor,\n        name: Optional[str] = None,\n        fields: Optional[Dict[str, Any]] = None,\n        transport_mode: TensorTransportMode = \"default\",\n        *args,\n        **kwargs,\n    ):\n\n        if not isinstance(data, torch.Tensor):\n            raise TypeError(\n                f\"Input 'data' must be a torch.Tensor, but got {type(data)}\"\n            )\n\n        instance = data.as_subclass(cls)\n\n        instance._metadata = {\n            \"name\": name,\n            \"fields\": fields if fields is not None else {},\n            \"transport_mode\": transport_mode,\n        }\n\n        return instance\n\n    def __getstate__(self):\n        \"\"\"\n        Called during pickling. Implements the serialization logic.\n        \"\"\"\n        # acquire all serialize metadata from _metadata","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/managers/mm_utils.py#L114-L150","documentation":"A Tensor-subclass __new__ (used for SGLang's MM tensor wrapper) requires the 'data' argument to already be a torch.Tensor; it reclasses the tensor rather than constructing one, so lists/ndarrays are type errors.","triggerScenarios":"Constructing the wrapper with a numpy array or nested list, e.g. cls(np.array(...)) or cls([[1,2]]) instead of cls(torch.tensor(...)).","commonSituations":"Porting code from numpy pipelines into the MM utils path; test fixtures passing raw arrays.","solutions":["Wrap data first: torch.as_tensor(data) or torch.from_numpy(arr)","Check isinstance(data, torch.Tensor) before constructing"],"exampleFix":"// before\nt = mm_tensor_cls(numpy_array)\n// after\nt = mm_tensor_cls(torch.from_numpy(numpy_array))","handlingStrategy":"type-guard","validationCode":"if not isinstance(data, torch.Tensor):\n    data = torch.as_tensor(data)","typeGuard":"def is_tensor(x): return isinstance(x, torch.Tensor)","tryCatchPattern":"try:\n    t = WrappedTensor(data)\nexcept TypeError:\n    t = WrappedTensor(torch.as_tensor(data))","preventionTips":["Convert numpy/list inputs at API boundaries once"],"tags":["sglang","torch","type-error","multimodal"],"backgroundTag":"wrong-argument-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}