{"record":{"id":"b1ec3e278611f03d","repo":"pandas-dev/pandas","slug":"can-only-use-the-struct-accessor-with-struct-p","errorCode":null,"errorMessage":"Can only use the '.struct' accessor with 'struct[pyarrow]' dtype, not {dtype}.","messagePattern":"Can only use the '\\.struct' accessor with 'struct\\[pyarrow\\]' dtype, not (.+?)\\.","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/accessors.py","lineNumber":52,"sourceCode":"    @abstractmethod\n    def __init__(self, data, validation_msg: str) -> None:\n        self._data = data\n        self._validation_msg = validation_msg\n        self._validate(data)\n\n    @abstractmethod\n    def _is_valid_pyarrow_dtype(self, pyarrow_dtype) -> bool:\n        pass\n\n    def _validate(self, data) -> None:\n        dtype = data.dtype\n        if not HAS_PYARROW or not isinstance(dtype, ArrowDtype):\n            # Raise AttributeError so that inspect can handle non-struct Series.\n            raise AttributeError(self._validation_msg.format(dtype=dtype))\n\n        if not self._is_valid_pyarrow_dtype(dtype.pyarrow_dtype):\n            # Raise AttributeError so that inspect can handle invalid Series.\n            raise AttributeError(self._validation_msg.format(dtype=dtype))\n\n    @property\n    def _pa_array(self):\n        return self._data.array._pa_array\n\n\nclass ListAccessor(ArrowAccessor):\n    \"\"\"\n    Accessor object for list data properties of the Series values.\n\n    Parameters\n    ----------\n    data : Series\n        Series containing Arrow list data.\n    \"\"\"\n\n    def __init__(self, data=None) -> None:\n        super().__init__(","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/accessors.py#L34-L70","documentation":"The .struct accessor requires dtype struct[pyarrow]. Line 52 raises AttributeError when the dtype IS an ArrowDtype but the underlying pyarrow type is not a struct (e.g. int64[pyarrow], string[pyarrow], list[pyarrow]). AttributeError is used so hasattr/inspect treat the accessor as absent on non-struct columns.","triggerScenarios":"s.struct.field('x') (or s.struct.dtypes) on a Series whose dtype is a non-struct pyarrow type such as int64[pyarrow], string[pyarrow], or list[pyarrow].","commonSituations":"Assuming a column is struct when it is a primitive pyarrow type; schema drift after data ingestion.","solutions":["Ensure the Series is built with a pa.struct([...]) dtype via pd.ArrowDtype.","Reconstruct the column from dict/list data with the struct dtype before using .struct."],"exampleFix":"// before\ns.struct.field(\"a\")  # s.dtype == string[pyarrow]\n// after\nimport pyarrow as pa\ns = pd.Series([...], dtype=pd.ArrowDtype(pa.struct([(\"a\", pa.string())])))\ns.struct.field(\"a\")","handlingStrategy":"type-guard","validationCode":"def to_struct_pa(s, fields):\n    import pyarrow as pa\n    from pandas.core.dtypes.dtypes import ArrowDtype\n    if not (isinstance(s.dtype, ArrowDtype) and pa.types.is_struct(s.dtype.pyarrow_dtype)):\n        s = pd.Series(list(s), dtype=ArrowDtype(pa.struct(fields)))\n    return s","typeGuard":"def is_struct_pyarrow(s) -> bool:\n    import pyarrow as pa\n    from pandas.core.dtypes.dtypes import ArrowDtype\n    d = s.dtype\n    return isinstance(d, ArrowDtype) and pa.types.is_struct(d.pyarrow_dtype)","tryCatchPattern":null,"preventionTips":["Verify the pyarrow schema before calling .struct.field","Build struct columns explicitly with pa.struct([...]) dtype"],"tags":["pyarrow","struct-accessor","dtype","attribute-error"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}