{"record":{"id":"824fb502a30763cd","repo":"pola-rs/polars","slug":"cannot-specify-both-infer-schema-length-and-rea","errorCode":null,"errorMessage":"cannot specify both `infer_schema_length` and `read_options[\"schema_sample_rows\"]`","messagePattern":"cannot specify both `infer_schema_length` and `read_options\\[\"schema_sample_rows\"\\]`","errorType":"exception","errorClass":"ParameterCollisionError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/spreadsheet/functions.py","lineNumber":748,"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":730,"sourceCodeEnd":766,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/io/spreadsheet/functions.py#L730-L766","documentation":"polars.exceptions.ParameterCollisionError raised while normalizing read_excel options for the calamine engine: the top-level infer_schema_length (any value other than the default N_INFER_DEFAULT) collides with read_options['schema_sample_rows']. Both control how many rows calamine samples to infer dtypes, so polars refuses the ambiguous pair during option normalization.","triggerScenarios":"pl.read_excel('f.xlsx', engine='calamine', infer_schema_length=500, read_options={'schema_sample_rows': 500}). Any non-default infer_schema_length together with 'schema_sample_rows' present in read_options.","commonSituations":"Porting python-calamine code that used schema_sample_rows while also tuning polars' infer_schema_length; shared read_options dicts reused across engines where xlsx2csv/calamine options accumulate.","solutions":["Use the top-level parameter: pl.read_excel(..., infer_schema_length=500) and remove 'schema_sample_rows' from read_options.","Or keep it engine-level: read_options={'schema_sample_rows': 500} with infer_schema_length left at its default.","Note the default value is allowed through — set infer_schema_length=None explicitly in wrappers only when you also clear schema_sample_rows."],"exampleFix":"# before\npl.read_excel('f.xlsx', infer_schema_length=500, read_options={'schema_sample_rows': 1000})\n\n# after\npl.read_excel('f.xlsx', infer_schema_length=1000)","handlingStrategy":"validation","validationCode":"ro = dict(read_options or {})\nif infer_schema_length is not None and 'schema_sample_rows' in ro:\n    ro.pop('schema_sample_rows')  # keep the top-level parameter\npl.read_excel(path, infer_schema_length=infer_schema_length, read_options=ro)","typeGuard":null,"tryCatchPattern":"try:\n    pl.read_excel(path, infer_schema_length=n, read_options=read_options)\nexcept pl.exceptions.ParameterCollisionError as e:\n    if 'schema_sample_rows' in str(e):\n        ro = {k: v for k, v in (read_options or {}).items() if k != 'schema_sample_rows'}\n        pl.read_excel(path, infer_schema_length=n, read_options=ro)\n    else:\n        raise","preventionTips":["Set the inference sample size in exactly one place: infer_schema_length or schema_sample_rows.","When porting calamine reader code, translate schema_sample_rows to infer_schema_length.","The collision only fires for non-default infer_schema_length — still avoid keeping both for clarity."],"tags":["excel","spreadsheet","read-excel","calamine","parameter-conflict","schema-inference"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}