pola-rs/polars · error · TypeError
invalid sentinel value for column of type {column_dtype}: {n
Error message
invalid sentinel value for column of type {column_dtype}: {null_value!r} What it means
For USE_SENTINEL null handling, Polars builds pl.Series([null_value]) and, for temporal columns, casts it to the column dtype before comparing with the data. If that cast raises InvalidOperationError, Polars re-raises it as TypeError naming the column dtype and the sentinel value. The producer advertised a sentinel that is not representable in the column's data type.
Source
Thrown at py-polars/src/polars/interchange/from_dataframe.py:291
elif null_type == ColumnNullType.USE_NAN:
if not allow_copy:
msg = "bitmask must be constructed"
raise CopyNotAllowedError(msg)
return data.is_not_nan()
elif null_type == ColumnNullType.USE_SENTINEL:
if not allow_copy:
msg = "bitmask must be constructed"
raise CopyNotAllowedError(msg)
sentinel = pl.Series([null_value])
try:
if column_dtype.is_temporal():
sentinel = sentinel.cast(column_dtype)
return data != sentinel # noqa: TRY300
except InvalidOperationError as e:
msg = f"invalid sentinel value for column of type {column_dtype}: {null_value!r}"
raise TypeError(msg) from e
else:
msg = f"unsupported null type: {null_type!r}"
raise NotImplementedError(msg)
def _construct_validity_buffer_from_bitmask(
buffer: Buffer,
null_value: int,
length: int,
offset: int = 0,
*,
allow_copy: bool,
) -> Series:
buffer_info = (buffer.ptr, offset, length)
s = pl.Series._from_buffer(Boolean, buffer_info, buffer)
if null_value != 0:View on GitHub (pinned to df599052da)
Solutions
- Fix the producer to report a sentinel castable to the column dtype (an in-range integer for temporal types)
- If the sentinel must stay as-is, import the column as its raw physical type and reconstruct nulls in Polars manually
- Catch TypeError around the conversion and fall back to a manual parsing path
Defensive patterns
Strategy: try-catch
Validate before calling
def sentinel_is_castable(df) -> bool:
import polars as pl
from polars.interchange.protocol import ColumnNullType
proto = df.__dataframe__(allow_copy=False)
for col in proto.get_columns():
null_type, null_value = col.describe_null()
if null_type == ColumnNullType.USE_SENTINEL:
try:
pl.Series([null_value])
except Exception:
return False
return True Try / catch
try:
out = pl.from_dataframe(df)
except TypeError as e:
if 'invalid sentinel value' in str(e):
# producer sentinel metadata is wrong; import raw and fix nulls manually
out = pl.from_dataframe(df_raw)
else:
raise Prevention
- Producers: report sentinels that are representable in the column dtype (in-range integers for temporal types)
- Unit-test sentinel metadata against the actual column dtypes in custom producers
- Prefer explicit validity masks over sentinel nulls in any new producer code
When it happens
Trigger: A temporal column whose describe_null sentinel cannot be cast to that dtype - e.g. a string sentinel for a Datetime/Date column, or an integer sentinel outside the Date value range.
Common situations: Custom producers with mismatched sentinel metadata; porting systems where null markers were stored as strings or out-of-range codes; hand-written __dataframe__ implementations that copy sentinel values from another column type.
Related errors
- `df` of type {qualified_type_name(df)!r} does not support th
- cannot create String column without an offsets buffer
- non-dictionary categoricals are not yet supported
- bitmask must be constructed
- unsupported null type: {null_type!r}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/0301671ca0cc7db3.
Report an issue: GitHub.