{"record":{"id":"0301671ca0cc7db3","repo":"pola-rs/polars","slug":"invalid-sentinel-value-for-column-of-type-column","errorCode":null,"errorMessage":"invalid sentinel value for column of type {column_dtype}: {null_value!r}","messagePattern":"invalid sentinel value for column of type (.+?): (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/interchange/from_dataframe.py","lineNumber":291,"sourceCode":"    elif null_type == ColumnNullType.USE_NAN:\n        if not allow_copy:\n            msg = \"bitmask must be constructed\"\n            raise CopyNotAllowedError(msg)\n        return data.is_not_nan()\n\n    elif null_type == ColumnNullType.USE_SENTINEL:\n        if not allow_copy:\n            msg = \"bitmask must be constructed\"\n            raise CopyNotAllowedError(msg)\n\n        sentinel = pl.Series([null_value])\n        try:\n            if column_dtype.is_temporal():\n                sentinel = sentinel.cast(column_dtype)\n            return data != sentinel  # noqa: TRY300\n        except InvalidOperationError as e:\n            msg = f\"invalid sentinel value for column of type {column_dtype}: {null_value!r}\"\n            raise TypeError(msg) from e\n\n    else:\n        msg = f\"unsupported null type: {null_type!r}\"\n        raise NotImplementedError(msg)\n\n\ndef _construct_validity_buffer_from_bitmask(\n    buffer: Buffer,\n    null_value: int,\n    length: int,\n    offset: int = 0,\n    *,\n    allow_copy: bool,\n) -> Series:\n    buffer_info = (buffer.ptr, offset, length)\n    s = pl.Series._from_buffer(Boolean, buffer_info, buffer)\n\n    if null_value != 0:","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/pola-rs/polars/blob/9b5d73fd00236295624374b075d16b1fe6ec6df9/py-polars/src/polars/interchange/from_dataframe.py#L273-L309","documentation":"For USE_SENTINEL columns, Polars builds a one-element Series of the sentinel value, casts it to the column dtype when temporal, and compares it against the data. If that cast/comparison raises InvalidOperationError (sentinel cannot be represented in the column's dtype), it is re-raised as TypeError naming the column dtype and the offending sentinel value.","triggerScenarios":"pl.from_dataframe(obj) where a column declares a sentinel incompatible with its physical dtype — e.g. sentinel -1 on a UInt8 column, or a string sentinel on a temporal column. The producer's describe_null() returned a value that cannot legally appear in the column.","commonSituations":"Producers hardcoding -1 as a universal missing-value marker regardless of unsigned/physical dtype; format specs where the sentinel was designed for the logical type, not the physical buffer type.","solutions":["Fix the producer to use a sentinel representable in the column's dtype (e.g. 255 for UInt8) or a validity bitmask.","Convert the affected column through another path (e.g. pyarrow with explicit null replacement) before importing.","Catch TypeError from from_dataframe and fall back to a producer-specific converter for that frame."],"exampleFix":"# producer side, before\n return (ColumnNullType.USE_SENTINEL, -1)  # on a UInt8 column -> TypeError\n# after\n return (ColumnNullType.USE_SENTINEL, 255)  # representable in UInt8\n# or, cleanest:\n return (ColumnNullType.USE_BITMAP, 0)","handlingStrategy":"try-catch","validationCode":"# verify the sentinel is representable before importing\ndef sentinel_ok(col) -> bool:\n    null_type, sentinel = col.describe_null()\n    if null_type != ColumnNullType.USE_SENTINEL:\n        return True\n    try:\n        s = pl.Series([sentinel])\n        if col.dtype[0] == DtypeKind.DATETIME:\n            s = s.cast(dtype_to_polars_dtype(col.dtype))\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    df = pl.from_dataframe(obj)\nexcept TypeError as e:\n    if \"invalid sentinel value\" not in str(e):\n        raise\n    # producer bug: fix describe_null() to return a dtype-representable sentinel,\n    # or convert the column via pyarrow with explicit null handling","preventionTips":["Choose sentinels valid for the physical buffer dtype, not the logical column type.","Prefer bitmasks over sentinels in any producer you control.","Validate sentinel/dtype pairs in producer unit tests."],"tags":["polars","interchange-protocol","sentinel","validity","typeerror"],"backgroundTag":"invalid-sentinel-value","analyzedSha":"9b5d73fd00236295624374b075d16b1fe6ec6df9","analyzedAt":"2026-08-19T12:15:06.350Z","contentChangedAt":"2026-08-19T12:15:06.350Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}