pola-rs/polars · error

invalid call to `get_strftime_format`; fmt=

Error message

invalid call to `get_strftime_format`; fmt={fmt:?}, dtype={dtype}

What it means

get_strftime_format maps a temporal DataType plus optional format to a strftime format string and only implements the known temporal dtype/format combinations (Date, Datetime with/without tz, Time). Any other pairing hits an unimplemented!() guard. It is an internal assertion that the dtype being stringified is a supported temporal one.

Solutions

  1. Cast the column to the intended temporal dtype before formatting: df.col("ts")?.cast(&DataType::Datetime(TimeUnit::Microseconds, None)).
  2. Use dt.strftime(...) expressions only on Date/Datetime/Time typed columns.
  3. Check the series dtype with series.dtype() and handle non-temporal dtypes before calling to_string.
  4. If you provide an explicit fmt argument, ensure the dtype is temporal so the (fmt, dtype) pair is valid.

Example fix

// before
let s = df.column("ts")?.to_string(); // ts is Int64 -> panics
// after
let s = df.column("ts")?
    .cast(&DataType::Datetime(TimeUnit::Microseconds, None))?
    .to_string();
Defensive patterns

Strategy: validation

Validate before calling

if !matches!(s.dtype(), DataType::Date | DataType::Time | DataType::Datetime(..)) {
    return Err(PolarsError::ComputeError("non-temporal dtype".into()));
}
let formatted = s.to_string();

Type guard

fn is_temporal_dtype(dt: &DataType) -> bool {
    matches!(dt, DataType::Date | DataType::Time | DataType::Datetime(..))
}

Try / catch

Check dtype before to_string; polars panics, so validate instead of catching:
let s = if is_temporal_dtype(series.dtype()) { series.to_string() } else { series.cast(&DataType::Datetime(...))?.to_string() };

Prevention

When it happens

Trigger: Calling to_string()/cast to String on a ChunkedArray whose dtype is not Date, Datetime, or Time (e.g. Int64 timestamps), or invoking get_strftime_format directly with an invalid (fmt, dtype) combination.

Common situations: Formatting a numeric timestamp column to string without casting to Datetime first; a series that lost its logical dtype (e.g. after a raw cast or from_arrow mapping issue); plugin/custom code passing unexpected dtype.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at crates/polars-core/src/chunked_array/temporal/conversion.rs:83

            match dtype {
                #[cfg(feature = "dtype-datetime")]
                DataType::Datetime(tu, tz) => match (tu, tz.is_some()) {
                    (TimeUnit::Milliseconds, true) => format!("%F{sep}%T%.3f%:z"),
                    (TimeUnit::Milliseconds, false) => format!("%F{sep}%T%.3f"),
                    (TimeUnit::Microseconds, true) => format!("%F{sep}%T%.6f%:z"),
                    (TimeUnit::Microseconds, false) => format!("%F{sep}%T%.6f"),
                    (TimeUnit::Nanoseconds, true) => format!("%F{sep}%T%.9f%:z"),
                    (TimeUnit::Nanoseconds, false) => format!("%F{sep}%T%.9f"),
                },
                #[cfg(feature = "dtype-date")]
                DataType::Date => "%F".to_string(),
                #[cfg(feature = "dtype-time")]
                DataType::Time => "%T%.f".to_string(),
                _ => {
                    let err = format!(
                        "invalid call to `get_strftime_format`; fmt={fmt:?}, dtype={dtype}"
                    );
                    unimplemented!("{}", err)
                },
            }
        };
        Ok(format_string)
    }
}

View on GitHub (pinned to fe841f959e)