{"record":{"id":"a3a60a1af21e0184","repo":"apache/beam","slug":"batch-batch-r-does-not-have-expected-shape-self-shape-r","errorCode":null,"errorMessage":"Batch {batch!r} does not have expected shape: {self.shape!r}","messagePattern":"Batch (.+?) does not have expected shape: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/typehints/batch.py","lineNumber":258,"sourceCode":"# 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):\n        return self.__key() == other.__key()\n\n      return NotImplemented\n\n    def __hash__(self) -> int:\n      return hash(self.__key())\n","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/typehints/batch.py#L240-L276","documentation":"For each declared dimension (except the N placeholder dimension), NumpyArray.type_check requires the batch array's actual shape to match. A batch with the wrong number of elements per batch or wrong element dimensions fails.","triggerScenarios":"Declaring NumpyArray[np.int64, (3,)] (fixed element size 3) but producing batches whose non-N dims are (4,) or whose element rows are size 2.","commonSituations":"Variable-length elements batched into an array with a fixed declared shape; ragged data that can't fit the declared per-element shape.","solutions":["Fix element construction so each element has the declared shape","Adjust the NumpyArray shape declaration to match real element dims","Pad/truncate elements to a uniform shape before batching"],"exampleFix":"// before\nnp.asarray(elements)  # elements of varying length, declared shape (3,)\n// after\nnp.asarray([e[:3] for e in elements], dtype=np.int64)  # enforce shape (3,)","handlingStrategy":"validation","validationCode":"import numpy as np\n# declared shape (3,) => every batch row must be length 3\nassert arr.ndim == len(declared_shape) and all(s == d for s, d in zip(arr.shape, declared_shape) if d != N)","typeGuard":"def has_shape(arr, declared_shape, N):\n    return all(sd == N or ad == sd for ad, sd in zip(arr.shape, declared_shape))","tryCatchPattern":null,"preventionTips":["Ensure all elements have identical, declared shapes before batching","Pad or truncate variable-length elements","Update the declared shape when element format changes"],"tags":["python","apache-beam","numpy","shape"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}