{"record":{"id":"7ca44d2be8eb2951","repo":"apache/beam","slug":"batch-batch-r-is-not-an-instance-of-torch-tensor","errorCode":null,"errorMessage":"Batch {batch!r} is not an instance of torch.Tensor","messagePattern":"Batch (.+?) is not an instance of torch\\.Tensor","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/typehints/pytorch_type_compatibility.py","lineNumber":99,"sourceCode":"  def combine_batches(self, batches):\n    return torch.cat(batches, dim=self.partition_dimension)\n\n  def get_length(self, batch):\n    return batch.size(dim=self.partition_dimension)\n\n  def estimate_byte_size(self, batch):\n    return batch.nelement() * batch.element_size()\n\n\nclass PytorchTypeHint():\n  class PytorchTypeConstraint(typehints.TypeConstraint):\n    def __init__(self, dtype, shape=()):\n      self.dtype = dtype\n      self.shape = shape\n\n    def type_check(self, batch):\n      if not isinstance(batch, torch.Tensor):\n        raise TypeError(f\"Batch {batch!r} is not an instance of torch.Tensor\")\n      if not batch.dtype == self.dtype:\n        raise TypeError(\n            f\"Batch {batch!r} does not have expected dtype: {self.dtype!r}\")\n\n      for dim in range(len(self.shape)):\n        if not self.shape[dim] == N and not batch.shape[dim] == self.shape[dim]:\n          raise TypeError(\n              f\"Batch {batch!r} does not have expected shape: {self.shape!r}\")\n\n    def _consistent_with_check_(self, sub):\n      # TODO Check sub against batch type, and element type\n      return True\n\n    def __key(self):\n      return (self.dtype, self.shape)\n\n    def __eq__(self, other) -> bool:\n      if isinstance(other, PytorchTypeHint.PytorchTypeConstraint):","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/typehints/pytorch_type_compatibility.py#L81-L117","documentation":"PytorchTypeConstraint.type_check validates that a batched value bound to a PytorchTensor[...] type hint is actually a torch.Tensor. Beam raises this TypeError during runtime type-check when the value flowing through the PCollection is not a torch.Tensor instance.","triggerScenarios":"Annotating a PCollection with PytorchTensor[torch.float32, (N, 128)] while the DoFn emits numpy arrays, Python lists, tuples, or dicts; type_check runs with Beam's default runtime type checking and the element fails isinstance(batch, torch.Tensor).","commonSituations":"Returning numpy arrays from a DoFn annotated as PytorchTensor, forgetting torch.from_numpy()/torch.as_tensor() after preprocessing, emitting lists from beam.BatchElements instead of stacked tensors, or type-check catching values produced before a torch conversion step.","solutions":["Convert the value to a tensor before it reaches the typed PCollection: torch.as_tensor(x) or torch.from_numpy(arr).","In a DoFn, return torch.stack(list_of_tensors) instead of a list/ndarray when the output hint is PytorchTensor.","If values are genuinely not tensors, correct the type hint (e.g. numpy typehints) instead of PytorchTensor.","As a last resort disable runtime type checking (--type_check=none), though this hides the underlying bug."],"exampleFix":"// before\nclass Preprocess(beam.DoFn):\n  def process(self, row):\n    yield row['features'].numpy()  # ndarray, hint says PytorchTensor\n// after\nclass Preprocess(beam.DoFn):\n  def process(self, row):\n    yield torch.as_tensor(row['features'])  # real torch.Tensor","handlingStrategy":"type-guard","validationCode":"def ensure_tensor(x):\n    if not isinstance(x, torch.Tensor):\n        x = torch.as_tensor(x)\n    return x","typeGuard":"def is_torch_tensor(x) -> bool:\n    return isinstance(x, torch.Tensor)","tryCatchPattern":"try:\n    emit(batch)\nexcept TypeError as e:\n    if 'is not an instance of torch.Tensor' in str(e):\n        emit(torch.as_tensor(batch))\n    else:\n        raise","preventionTips":["Always call torch.as_tensor()/torch.stack() before returning values from DoFns with PytorchTensor hints.","Keep Beam's default runtime type checking enabled so this fails fast at the boundary.","Do not reuse hints across PCollections holding different container types.","Convert numpy arrays with torch.from_numpy immediately at the source."],"tags":["apache-beam","pytorch","type-check","typehint"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}