{"record":{"id":"8eb713a7f446d9fb","repo":"pandas-dev/pandas","slug":"expected-hashable-got-type-col-name","errorCode":null,"errorMessage":"Expected Hashable, got: {type(col_name)}","messagePattern":"Expected Hashable, got: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/col.py","lineNumber":413,"sourceCode":"    --------\n\n    You can use `col` in `assign`.\n\n    >>> df = pd.DataFrame({\"name\": [\"beluga\", \"narwhal\"], \"speed\": [100, 110]})\n    >>> df.assign(name_titlecase=pd.col(\"name\").str.title())\n          name  speed name_titlecase\n    0   beluga    100         Beluga\n    1  narwhal    110        Narwhal\n\n    You can also use it for filtering.\n\n    >>> df.loc[pd.col(\"speed\") > 105]\n          name  speed\n    1  narwhal    110\n    \"\"\"\n    if not isinstance(col_name, Hashable):\n        msg = f\"Expected Hashable, got: {type(col_name)}\"\n        raise TypeError(msg)\n\n    def func(df: DataFrame) -> Series:\n        if col_name not in df.columns:\n            columns_str = str(df.columns.tolist())\n            max_len = 90\n            if len(columns_str) > max_len:\n                columns_str = columns_str[:max_len] + \"...]\"\n\n            msg = (\n                f\"Column '{col_name}' not found in given DataFrame.\\n\\n\"\n                f\"Hint: did you mean one of {columns_str} instead?\"\n            )\n            raise ValueError(msg)\n        return df[col_name]\n\n    return Expression(func, f\"col({col_name!r})\")\n\n","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/col.py#L395-L431","documentation":"Raised by the pandas.col() factory when col_name is not an instance of Hashable. pd.col(name) builds a deferred column reference for use in assign/loc/query; the column label must be hashable so it can be looked up in df.columns later. Lists, dicts, ndarrays, and other unhashable types are rejected up front with a TypeError naming the actual type received.","triggerScenarios":"pd.col(['a','b']) (list of names); pd.col({'a':1}); pd.col(np.array([1,2])); pd.col([None]) — all unhashable. Passing a tuple is allowed (tuples are hashable).","commonSituations":"Confusing pd.col (single-column reference) with selecting multiple columns; passing a parsed JSON list directly; refactoring old lambda df: df[['a','b']] code into pd.col without splitting.","solutions":["Pass a single hashable label: pd.col('a') or pd.col(0).","For multiple columns, compose Expressions: pd.col('a') + pd.col('b').","If the name is dynamic, validate isinstance(name, Hashable) before calling pd.col."],"exampleFix":"// before\nexpr = pd.col(['speed', 'weight'])\n// after\nexpr = pd.col('speed') + pd.col('weight')","handlingStrategy":"type-guard","validationCode":"from collections.abc import Hashable\nif not isinstance(name, Hashable):\n    raise TypeError(f'pd.col expects a Hashable, got {type(name)}')\nexpr = pd.col(name)","typeGuard":"def is_hashable(x) -> bool:\n    try:\n        hash(x)\n    except TypeError:\n        return False\n    return True","tryCatchPattern":null,"preventionTips":["Pass a single column label, not a list, to pd.col.","Validate Hashable before constructing an Expression dynamically."],"tags":["type-error","col","hashable","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}