pola-rs/polars · error

invalid `time_unit`\n\nExpected one of

Error message

invalid `time_unit`\n\nExpected one of {'ns','us','ms'}, got {time_unit!r}.

What it means

Raised by the Datetime constructor's entry-point guard: the time_unit argument is not one of the resolutions polars can physically store. Datetimes are represented as 64-bit integers counting ticks since the Unix epoch, and only 'ns', 'us', and 'ms' tick sizes are supported; any other string (or non-string value) fails this membership check before the type is built.

Solutions

  1. Use one of 'ms', 'us', 'ns' (default 'us')
  2. Normalize/validate config-supplied time units before constructing `pl.Datetime`
  3. Lowercase the input: `pl.Datetime(time_unit.lower())` if it may be uppercase

Example fix

// before
pl.Datetime('s')
// after
pl.Datetime('us')
Defensive patterns

Strategy: validation

Validate before calling

TIME_UNITS = {'ms', 'us', 'ns'}
if time_unit not in TIME_UNITS:
    raise ValueError(f'time_unit must be one of {TIME_UNITS}, got {time_unit!r}')

Type guard

from typing import Literal, TypeGuard
def is_valid_time_unit(u: object) -> TypeGuard[Literal['ms','us','ns']]:
    return u in ('ms', 'us', 'ns')

Try / catch

try:
    dt = pl.Datetime(time_unit)
except ValueError as e:
    if 'invalid `time_unit`' in str(e):
        dt = pl.Datetime('us')
    else:
        raise

Prevention

When it happens

Trigger: `pl.Datetime('s')`, `pl.Datetime('seconds')`, `pl.Datetime('')`, `pl.Datetime(None)` or any string other than 'ms', 'us', 'ns'.

Common situations: Developers expect seconds ('s') to be supported (as in pandas/DuckDB), or pass a time unit read from config in the wrong case ('US', 'NS').

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/e10dfcdf32ad8c50. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/datatypes/classes.py:608

    -----
    The underlying representation of this type is a 64-bit signed integer.
    The integer indicates the number of time units since the Unix epoch
    (1970-01-01 00:00:00). The number can be negative to indicate datetimes before the
    epoch.
    """

    time_unit: TimeUnit
    time_zone: str | None

    def __init__(
        self, time_unit: TimeUnit = "us", time_zone: str | tzinfo | None = None
    ) -> None:
        if time_unit not in ("ms", "us", "ns"):
            msg = (
                "invalid `time_unit`"
                f"\n\nExpected one of {{'ns','us','ms'}}, got {time_unit!r}."
            )
            raise ValueError(msg)

        if isinstance(time_zone, tzinfo):
            time_zone = str(time_zone)

        self.time_unit = time_unit
        self.time_zone = time_zone

    def __eq__(self, other: PolarsDataType) -> bool:  # type: ignore[override]
        # allow comparing object instances to class
        if type(other) is DataTypeClass and issubclass(other, Datetime):
            return True
        elif isinstance(other, Datetime):
            return (
                self.time_unit == other.time_unit and self.time_zone == other.time_zone
            )
        else:
            return False

View on GitHub (pinned to fe841f959e)