{"record":{"id":"ad7319b13b9e1cdf","repo":"run-llama/llama_index","slug":"unhandled-shape-array-shape","errorCode":null,"errorMessage":"Unhandled shape {array.shape}.","messagePattern":"Unhandled shape (.+?)\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/embeddings/pooling.py","lineNumber":40,"sourceCode":"    @overload\n    def cls_pooling(cls, array: np.ndarray) -> np.ndarray: ...\n\n    @classmethod\n    @overload\n    # TODO: Remove this `type: ignore` after the false positive problem\n    #  is addressed in mypy: https://github.com/python/mypy/issues/15683 .\n    def cls_pooling(cls, array: \"torch.Tensor\") -> \"torch.Tensor\":  # type: ignore\n        ...\n\n    @classmethod\n    def cls_pooling(\n        cls, array: \"Union[np.ndarray, torch.Tensor]\"\n    ) -> \"Union[np.ndarray, torch.Tensor]\":\n        if len(array.shape) == 3:\n            return array[:, 0]\n        if len(array.shape) == 2:\n            return array[0]\n        raise NotImplementedError(f\"Unhandled shape {array.shape}.\")\n\n    @classmethod\n    def mean_pooling(cls, array: np.ndarray) -> np.ndarray:\n        if len(array.shape) == 3:\n            return array.mean(axis=1)\n        if len(array.shape) == 2:\n            return array.mean(axis=0)\n        raise NotImplementedError(f\"Unhandled shape {array.shape}.\")\n","sourceCodeStart":22,"sourceCodeEnd":49,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/embeddings/pooling.py#L22-L49","documentation":"PoolEmbedding.cls_pooling reduces an embedding tensor to its [CLS] token representation and only understands 3-D (batch, tokens, dim) and 2-D (tokens, dim) arrays. A 1-D vector (single already-pooled embedding) or 4-D+ array has no token axis to select from, so pooling is not implemented for it and NotImplementedError is raised.","triggerScenarios":"Passing a single 1-D embedding vector (shape (dim,)) into cls_pooling; feeding 4-D image-feature tensors; calling get_text_embedding on a model whose backend already returns pooled 1-D vectors.","commonSituations":"Writing a custom multi-modal embedding around PoolEmbedding; backends/version changes that return pre-pooled vectors; batching logic that squeezes the wrong axis.","solutions":["Ensure input is (batch, tokens, dim) — keep the batch dimension even for one text: array[None, ...] or tensor.unsqueeze(0)","If vectors are already pooled (1-D), skip pooling entirely and return them as-is","Reshape 4-D inputs to 3-D by merging leading dimensions before pooling"],"exampleFix":"// before\npooled = PoolEmbedding.cls_pooling(vec)  # vec.shape == (384,) -> NotImplementedError\n\n// after\nif vec.ndim == 1:\n    pooled = vec  # already pooled\nelse:\n    pooled = PoolEmbedding.cls_pooling(vec[None, :] if vec.ndim == 2 else vec)","handlingStrategy":"type-guard","validationCode":"assert array.ndim in (2, 3), f\"expected 2D/3D, got {array.shape}\"","typeGuard":"def is_poolable(array) -> bool:\n    return getattr(array, \"ndim\", 0) in (2, 3)","tryCatchPattern":"try:\n    pooled = PoolEmbedding.cls_pooling(array)\nexcept NotImplementedError:\n    pooled = array  # assume already-pooled 1-D vector","preventionTips":["Keep batch and token dims: never squeeze pooled inputs to 1-D before pooling","Log array.shape in custom embedding wrappers before calling pooling helpers","Unit-test your embedding wrapper with batch sizes 1 and N to catch rank bugs"],"tags":["embeddings","pooling","tensor-shape","multi-modal"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}