{"record":{"id":"29b6345bcb7b0f73","repo":"apache/beam","slug":"batch-batch-r-is-not-an-instance-of-ndarray","errorCode":null,"errorMessage":"Batch {batch!r} is not an instance of ndarray","messagePattern":"Batch (.+?) is not an instance of ndarray","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/typehints/batch.py","lineNumber":251,"sourceCode":"    return np.size(batch, axis=self.partition_dimension)\n\n  def estimate_byte_size(self, batch):\n    return batch.nbytes\n\n\n# numpy is starting to add typehints, which we should support\n# https://numpy.org/doc/stable/reference/typing.html for now they don't allow\n# specifying shape, seems to be coming after\n# https://www.python.org/dev/peps/pep-0646/\nclass NumpyTypeHint():\n  class NumpyTypeConstraint(typehints.TypeConstraint):\n    def __init__(self, dtype, shape=()):\n      self.dtype = np.dtype(dtype)\n      self.shape = shape\n\n    def type_check(self, batch):\n      if not isinstance(batch, np.ndarray):\n        raise TypeError(f\"Batch {batch!r} is not an instance of ndarray\")\n      if not np.issubdtype(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, NumpyTypeHint.NumpyTypeConstraint):","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/typehints/batch.py#L233-L269","documentation":"NumpyTypeConstraint.type_check is the runtime type guard for NumpyArray[...] hints during pipeline execution: the batched value flowing through is not a numpy.ndarray, so the declared constraint is violated.","triggerScenarios":"Emitting batches that are plain Python lists from a DoFn while the declared batch type is NumpyArray/np.ndarray, then beam runtime type-checking rejects them.","commonSituations":"Switching a pipeline from list batching to numpy batching without changing produce_batch/output code; returning array-likes that aren't np.ndarray.","solutions":["Ensure batched outputs are np.ndarray instances (np.asarray(list) as needed)","Change the declared batch type to List[T] if you actually produce lists","Use a BatchElements transform with the matching converter to produce batches"],"exampleFix":"// before\nreturn list(elements)  # with numpy batch type declared\n// after\nreturn np.asarray(list(elements), dtype=np.int64)","handlingStrategy":"validation","validationCode":"import numpy as np\nassert isinstance(batch, np.ndarray), 'batch must be np.ndarray'","typeGuard":"import numpy as np\ndef is_ndarray(x):\n    return isinstance(x, np.ndarray)","tryCatchPattern":"try:\n    check_batch(batch)\nexcept TypeError as e:\n    batch = np.asarray(batch)  # coerce array-likes","preventionTips":["Always produce batches with np.asarray(...)","Match your batch producer to the declared converter","Don't return raw lists when a numpy batch type is declared"],"tags":["python","apache-beam","numpy","type-check"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}