pola-rs/polars · error · ValueError
`dtype` must be of type {Date, Datetime, Time}
Error message
`dtype` must be of type {Date, Datetime, Time} What it means
Expr.str.strptime is a dispatcher over the target temporal dtype: dtype=pl.Date routes to to_date, pl.Datetime to to_datetime (honouring time_unit/time_zone if given an instantiated class), and pl.Time to to_time. Any dtype outside {Date, Datetime, Time} — numeric types, String, Duration, None — reaches the else branch and raises ValueError, because string parsing to that type is undefined.
Source
Thrown at py-polars/src/polars/expr/string.py:332
if dtype == Date:
return self.to_date(format, strict=strict, exact=exact, cache=cache)
elif dtype == Datetime:
time_unit = getattr(dtype, "time_unit", None)
time_zone = getattr(dtype, "time_zone", None)
return self.to_datetime(
format,
time_unit=time_unit,
time_zone=time_zone,
strict=strict,
exact=exact,
cache=cache,
ambiguous=ambiguous,
)
elif dtype == Time:
return self.to_time(format, strict=strict, cache=cache)
else:
msg = "`dtype` must be of type {Date, Datetime, Time}"
raise ValueError(msg)
@deprecate_nonkeyword_arguments(allowed_args=["self"], version="1.20.0")
@unstable()
def to_decimal(self, *, scale: int) -> Expr:
"""
Convert a String column into a Decimal column.
.. engine-support:: in-memory, streaming, distributed
.. warning::
This functionality is considered **unstable**. It may be changed
at any point without it being considered a breaking change.
.. versionchanged:: 1.20.0
Parameter `inference_length` should now be passed as a keyword argument.
.. versionchanged:: 1.33.0
Parameter `inference_length` was removed and `scale` was made non-optional.View on GitHub (pinned to df599052da)
Solutions
- For numeric-looking strings use .cast(pl.Int64) (add .str.strip_chars() if needed) — str.strptime is temporal-only.
- For timestamps pass pl.Date, pl.Datetime, or pl.Time.
- In generic pipelines, branch: temporal spec -> str.strptime, otherwise -> cast.
Example fix
# before
pl.col('s').str.strptime(pl.Int64, strict=False)
# after
pl.col('s').cast(pl.Int64, strict=False)
# temporal stays:
pl.col('s').str.strptime(pl.Datetime, '%Y-%m-%d') Defensive patterns
Strategy: type-guard
Validate before calling
import polars as pl
from polars import Date, Datetime, Time
assert dtype in (Date, Datetime, Time) or isinstance(dtype, (Date, Datetime, Time)), f'strptime dtype must be temporal, got {dtype!r}' Type guard
import polars as pl
def is_temporal_dtype(dt) -> bool:
return dt in (pl.Date, pl.Datetime, pl.Time) or isinstance(dt, (pl.Date, pl.Datetime, pl.Time)) Prevention
- str.strptime is for Date/Datetime/Time only — everything else is a cast.
- Passing instantiated classes like pl.Datetime('ms', 'UTC') is supported and recommended for timezone-aware parsing.
When it happens
Trigger: pl.col('s').str.strptime(pl.Int64), str.strptime(None) via an unset variable, or str.strptime(pl.String). Parametrized temporal classes (pl.Datetime('ms')) are fine — they compare equal to the base class.
Common situations: Parsing strings that actually hold numbers (e.g. '123') with strptime instead of cast; dtype passed through a generic column-spec where non-temporal types slip in; forgetting that ISO strings to Duration is not supported via strptime.
Related errors
- reinterpret requires exactly one of `signed` or `dtype` to b
- cannot specify both `value` and `strategy`
- must specify either a fill `value` or `strategy`
- strategy {strategy!r} is not supported
- cannot specify both `n` and `fraction`
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/6b68152f636136ee.
Report an issue: GitHub.