{"record":{"id":"df26de8b04595a7b","repo":"pandas-dev/pandas","slug":"dtype-does-not-have-a-resolution","errorCode":null,"errorMessage":"{dtype=} does not have a resolution.","messagePattern":"(.+?) does not have a resolution\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimelike.py","lineNumber":2543,"sourceCode":"\ndef dtype_to_unit(dtype: DatetimeTZDtype | np.dtype | ArrowDtype) -> str:\n    \"\"\"\n    Return the unit str corresponding to the dtype's resolution.\n\n    Parameters\n    ----------\n    dtype : DatetimeTZDtype or np.dtype\n        If np.dtype, we assume it is a datetime64 dtype.\n\n    Returns\n    -------\n    str\n    \"\"\"\n    if isinstance(dtype, DatetimeTZDtype):\n        return dtype.unit\n    elif isinstance(dtype, ArrowDtype):\n        if dtype.kind not in \"mM\":\n            raise ValueError(f\"{dtype=} does not have a resolution.\")\n        return dtype.pyarrow_dtype.unit\n    return np.datetime_data(dtype)[0]\n","sourceCodeStart":2525,"sourceCodeEnd":2546,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimelike.py#L2525-L2546","documentation":"Raised by dtype_to_unit when given an ArrowDtype whose kind is not 'm' (timedelta) or 'M' (datetime). The function exists to extract a time resolution string; for arrow types that have no temporal resolution (e.g. pyarrow strings, ints, bools) the concept is undefined, so it refuses rather than returning a nonsense unit.","triggerScenarios":"Calling internal dtype_to_unit(dtype) with an ArrowExtensionArray dtype that is not a pyarrow timestamp/duration; indirectly through code that converts a mixed list of dtypes to units assuming all are temporal.","commonSituations":"Interoperability code that iterates DataFrame dtypes and assumes every Arrow-backed column has a time resolution; passing an ArrowDtype accidentally where a DatetimeTZDtype/np.dtype was expected.","solutions":["Guard the call: only invoke dtype_to_unit when dtype.kind in 'mM'.","Filter to temporal columns before resolving units: [c for c in df.columns if df[c].dtype.kind in 'mM'].","If you intended a datetime, construct the right dtype: pd.ArrowDtype(pa.timestamp('us'))."],"exampleFix":"// before\nunit = dtype_to_unit(pd.ArrowDtype(pa.string()))  # ValueError: does not have a resolution\n\n// after\nif dtype.kind in 'mM':\n    unit = dtype_to_unit(dtype)\nelse:\n    unit = None","handlingStrategy":"type-guard","validationCode":"def safe_dtype_to_unit(dtype):\n    if isinstance(dtype, pd.ArrowDtype) and dtype.kind not in \"mM\":\n        return None  # or raise a descriptive error\n    return dtype_to_unit(dtype)","typeGuard":"def has_resolution(dtype) -> bool:\n    if isinstance(dtype, pd.ArrowDtype):\n        return dtype.kind in \"mM\"\n    return True","tryCatchPattern":"try:\n    unit = dtype_to_unit(dtype)\nexcept ValueError as e:\n    if \"does not have a resolution\" in str(e):\n        unit = None\n    else:\n        raise","preventionTips":["Filter to temporal columns before resolving units.","Check dtype.kind in 'mM' for ArrowDtype before calling dtype_to_unit.","Keep dtype dispatch tables mapping each kind to a resolver."],"tags":["pandas","arrow","dtype","resolution","validation"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}