pola-rs/polars · error

can only use timedelta string language with…

Error message

can only use timedelta string language with Date/Datetime/Duration/Time dtypes

What it means

Polars throws this panic when a string tolerance passed to a join is parsed as a 'timedelta string language' value (e.g. "2d") but the join key dtype is not temporal. The string tolerance only makes sense for Date/Datetime/Duration/Time join columns. Raised in `resolve_join` (called by `resolve_join_where`) in crates/polars-plan/src/plans/conversion/dsl_to_ir/join.rs.

Solutions

  1. Cast the join key column to Datetime (or Date/Duration/Time) before joining
  2. Remove the string tolerance argument, or pass a numeric tolerance matching the key dtype
  3. Verify the join key dtypes with df.schema / df.dtypes before the join

Example fix

// before
df.join(other, on="ts", tolerance="2d")  // ts is Int64 epoch millis
// after
df.with_columns(pl.col("ts").cast(pl.Datetime("ms")))
  .join(other, on="ts", tolerance="2d")
Defensive patterns

Strategy: validation

Validate before calling

schema = lf.collect_schema()
dtype = schema["ts"]
assert dtype in (pl.Date, pl.Datetime, pl.Duration, pl.Time), f"tolerance string requires temporal join key, got {dtype}"

Type guard

def is_temporal(dtype: pl.DataType) -> bool:
    return dtype in (pl.Date, pl.Datetime, pl.Duration, pl.Time)

Try / catch

try:
    result = lf.join(other, on="ts", tolerance="2d").collect()
except pl.exceptions.PanicException as e:
    if "timedelta string language" in str(e):
        result = lf.with_columns(pl.col("ts").cast(pl.Datetime("us"))).join(other, on="ts", tolerance="2d").collect()
    else:
        raise

Prevention

When it happens

Trigger: Calling `join(..., tolerance="2d")` (or join_where with tolerance_str) where the join key column dtype is an integer, string, float, etc., instead of a Date/Datetime/Duration/Time dtype.

Common situations: Using an asof-join style tolerance on integer timestamp columns (epoch millis), or after a schema change that converted a datetime column to a string/int.

Related errors


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

Appendix: source

Thrown at crates/polars-plan/src/plans/conversion/dsl_to_ir/join.rs:398

            {
                Datetime(tu, _) | Duration(tu) => {
                    let tolerance = match tu {
                        TimeUnit::Nanoseconds => duration.duration_ns(),
                        TimeUnit::Microseconds => duration.duration_us(),
                        TimeUnit::Milliseconds => duration.duration_ms(),
                    };
                    options.tolerance = Some(Scalar::from(tolerance))
                },
                Date => {
                    let days = (duration.duration_ms() / MILLISECONDS_IN_DAY) as i32;
                    options.tolerance = Some(Scalar::from(days))
                },
                Time => {
                    let tolerance = duration.duration_ns();
                    options.tolerance = Some(Scalar::from(tolerance))
                },
                _ => {
                    panic!(
                        "can only use timedelta string language with Date/Datetime/Duration/Time dtypes"
                    )
                },
            }
        }
    }

    // These are Arc<Schema>, into_owned is free.
    let schema_left = schema_left.into_owned();
    let schema_right = schema_right.into_owned();

    options.options = {
        let on = left_on.into_iter().zip(right_on).collect();
        match &options.args.how {
            #[cfg(feature = "asof_join")]
            JoinType::AsOf(_) => JoinTypeOptionsIR::AsOf { on },
            _ => JoinTypeOptionsIR::Equi {
                on,

View on GitHub (pinned to fe841f959e)