{"record":{"id":"a7a83a62896ed6df","repo":"pola-rs/polars","slug":"cannot-specify-both-columns-and-read-options-u","errorCode":null,"errorMessage":"cannot specify both `columns` and `read_options[\"use_columns\"]`","messagePattern":"cannot specify both `columns` and `read_options\\[\"use_columns\"\\]`","errorType":"validation","errorClass":"ParameterCollisionError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/spreadsheet/functions.py","lineNumber":753,"sourceCode":"    columns: Sequence[int] | Sequence[str] | None,\n    infer_schema_length: int | None,\n    has_header: bool,\n) -> dict[str, Any]:\n    \"\"\"Normalise top-level parameters to engine-specific 'read_options' dict.\"\"\"\n    read_options = (read_options or {}).copy()\n\n    if engine == \"calamine\":\n        if (\"use_columns\" in read_options) and columns:\n            msg = 'cannot specify both `columns` and `read_options[\"use_columns\"]`'\n            raise ParameterCollisionError(msg)\n        elif read_options.get(\"header_row\") is not None and has_header is False:\n            msg = 'the values of `has_header` and `read_options[\"header_row\"]` are not compatible'\n            raise ParameterCollisionError(msg)\n        elif (\"schema_sample_rows\" in read_options) and (\n            infer_schema_length != N_INFER_DEFAULT\n        ):\n            msg = 'cannot specify both `infer_schema_length` and `read_options[\"schema_sample_rows\"]`'\n            raise ParameterCollisionError(msg)\n\n        read_options[\"schema_sample_rows\"] = infer_schema_length\n        if has_header is False and \"header_row\" not in read_options:\n            read_options[\"header_row\"] = None\n\n    elif engine == \"xlsx2csv\":\n        if (\"columns\" in read_options) and columns:\n            msg = 'cannot specify both `columns` and `read_options[\"columns\"]`'\n            raise ParameterCollisionError(msg)\n        elif (\n            \"has_header\" in read_options\n            and read_options[\"has_header\"] is not has_header\n        ):\n            msg = 'the values of `has_header` and `read_options[\"has_header\"]` are not compatible'\n            raise ParameterCollisionError(msg)\n        elif (\"infer_schema_length\" in read_options) and (\n            infer_schema_length != N_INFER_DEFAULT\n        ):","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/io/spreadsheet/functions.py#L735-L771","documentation":"In `read_excel`, passing `columns` as a top-level argument while also supplying `read_options[\"use_columns\"]` creates a conflict: the function derives `use_columns` from `columns` and refuses to overwrite a user-specified value. Polars raises `ParameterCollisionError` to prevent ambiguous intent about which columns to read.","triggerScenarios":"Calling `pl.read_excel(source, columns=[...])` with an engine (fastexcel/xlsx2csv path) whose `read_options` dict also contains `use_columns`; in `_get_read_options` for the non-xlsx2csv engine branch.","commonSituations":"Migrating code that previously passed only `read_options={\"use_columns\": [...]}` and then adding the newer top-level `columns=` argument; copy-pasting examples that mix old and new APIs.","solutions":["Remove `use_columns` from `read_options` and pass columns only via the top-level `columns=` argument","Or remove the `columns=` argument and keep `read_options={\"use_columns\": [...]}`","Do not merge both config styles; pick one canonical way per call"],"exampleFix":"// before\npl.read_excel(f, columns=['a','b'], read_options={'use_columns': 'A:B'})\n// after\npl.read_excel(f, columns=['a','b'])","handlingStrategy":"validation","validationCode":"assert not ('use_columns' in read_options and columns), 'pass columns= or read_options[use_columns], not both'","typeGuard":null,"tryCatchPattern":"from polars.exceptions import ParameterCollisionError\ntry:\n    pl.read_excel(f, columns=cols, read_options=ro)\nexcept ParameterCollisionError as e:\n    ro.pop('use_columns', None)\n    df = pl.read_excel(f, columns=cols, read_options=ro)","preventionTips":["Keep column selection in one place (prefer top-level columns=)","Strip engine keys before merging shared read_options dicts","Write a thin wrapper around read_excel with a single columns parameter"],"tags":["python","polars","parameter-collision","excel"],"backgroundTag":"conflicting-config-options","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}