{"record":{"id":"009125c028309ae3","repo":"pola-rs/polars","slug":"cannot-specify-both-infer-schema-length-and-rea-009125","errorCode":null,"errorMessage":"cannot specify both `infer_schema_length` and `read_options[\"infer_schema_length\"]`","messagePattern":"cannot specify both `infer_schema_length` and `read_options\\[\"infer_schema_length\"\\]`","errorType":"exception","errorClass":"ParameterCollisionError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/spreadsheet/functions.py","lineNumber":768,"sourceCode":"        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        ):\n            msg = 'cannot specify both `infer_schema_length` and `read_options[\"infer_schema_length\"]`'\n            raise ParameterCollisionError(msg)\n\n        read_options[\"infer_schema_length\"] = infer_schema_length\n        if \"has_header\" not in read_options:\n            read_options[\"has_header\"] = has_header\n    else:\n        read_options[\"infer_schema_length\"] = infer_schema_length\n        read_options[\"has_header\"] = has_header\n\n    return read_options\n\n\ndef _get_sheet_names(\n    sheet_id: int | Sequence[int] | None,\n    sheet_name: str | Sequence[str] | None,\n    table_name: str | None,\n    worksheets: list[dict[str, Any]],\n) -> tuple[list[str], bool]:\n    \"\"\"Establish sheets to read; indicate if we are returning a dict frames.\"\"\"","sourceCodeStart":750,"sourceCodeEnd":786,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/io/spreadsheet/functions.py#L750-L786","documentation":"Raised by polars.read_excel (engine='xlsx2csv') in _get_read_options when 'infer_schema_length' is a key in read_options AND the top-level infer_schema_length differs from the polars default (N_INFER_DEFAULT = 100). It only fires when you explicitly changed the top-level value (including to None) and also put the key in read_options; otherwise the top-level value silently overwrites read_options after the check. The key is forwarded to the internal read_csv call used by the xlsx2csv engine.","triggerScenarios":"pl.read_excel(src, engine='xlsx2csv', infer_schema_length=None, read_options={'infer_schema_length': 500}) or infer_schema_length=1000 with the key also present in read_options.","commonSituations":"Tuning schema inference in two places because old examples put 'infer_schema_length' inside csv-style read_options; teams adding read_options wholesale from a shared config dict that already carries the key.","solutions":["Keep infer_schema_length only as the top-level parameter and remove the key from read_options","If you genuinely need the csv-level key, leave the top-level parameter at its default (do not set it)","Prefer read_options only for csv-specific keys (separator, truncate_ragged_lines, schema_overrides, etc.)"],"exampleFix":"# before\npl.read_excel(src, engine='xlsx2csv', infer_schema_length=None, read_options={'infer_schema_length': None, 'skip_rows': 2})\n\n# after\npl.read_excel(src, engine='xlsx2csv', infer_schema_length=None, read_options={'skip_rows': 2})","handlingStrategy":"validation","validationCode":"opts = dict(read_options or {})\nif 'infer_schema_length' in opts:\n    del opts['infer_schema_length']  # single source of truth: the top-level parameter\ndf = pl.read_excel(src, engine='xlsx2csv', infer_schema_length=infer_schema_length, read_options=opts)","typeGuard":null,"tryCatchPattern":"from polars.exceptions import ParameterCollisionError\ntry:\n    df = pl.read_excel(src, engine='xlsx2csv', infer_schema_length=isl, read_options=opts)\nexcept ParameterCollisionError as e:\n    if 'infer_schema_length' in str(e):\n        isl = opts.pop('infer_schema_length')\n        df = pl.read_excel(src, engine='xlsx2csv', infer_schema_length=isl, read_options=opts)\n    else:\n        raise","preventionTips":["Keep infer_schema_length top-level only; the default is 100, so the collision fires only when you changed it AND duplicated it in read_options","Do not splat whole read_csv option dicts into read_options without filtering","Test wrapper functions once with non-default infer_schema_length to surface collisions early"],"tags":["polars","excel","xlsx2csv","parameter-collision","infer-schema-length"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}