{"record":{"id":"35bfd5989dffa8e4","repo":"pola-rs/polars","slug":"can-only-use-timedelta-string-language-with-date-datetime","errorCode":null,"errorMessage":"can only use timedelta string language with Date/Datetime/Duration/Time dtypes","messagePattern":"can only use timedelta string language with Date/Datetime/Duration/Time dtypes","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-plan/src/plans/conversion/dsl_to_ir/join.rs","lineNumber":398,"sourceCode":"            {\n                Datetime(tu, _) | Duration(tu) => {\n                    let tolerance = match tu {\n                        TimeUnit::Nanoseconds => duration.duration_ns(),\n                        TimeUnit::Microseconds => duration.duration_us(),\n                        TimeUnit::Milliseconds => duration.duration_ms(),\n                    };\n                    options.tolerance = Some(Scalar::from(tolerance))\n                },\n                Date => {\n                    let days = (duration.duration_ms() / MILLISECONDS_IN_DAY) as i32;\n                    options.tolerance = Some(Scalar::from(days))\n                },\n                Time => {\n                    let tolerance = duration.duration_ns();\n                    options.tolerance = Some(Scalar::from(tolerance))\n                },\n                _ => {\n                    panic!(\n                        \"can only use timedelta string language with Date/Datetime/Duration/Time dtypes\"\n                    )\n                },\n            }\n        }\n    }\n\n    // These are Arc<Schema>, into_owned is free.\n    let schema_left = schema_left.into_owned();\n    let schema_right = schema_right.into_owned();\n\n    options.options = {\n        let on = left_on.into_iter().zip(right_on).collect();\n        match &options.args.how {\n            #[cfg(feature = \"asof_join\")]\n            JoinType::AsOf(_) => JoinTypeOptionsIR::AsOf { on },\n            _ => JoinTypeOptionsIR::Equi {\n                on,","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-plan/src/plans/conversion/dsl_to_ir/join.rs#L380-L416","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Cast the join key column to Datetime (or Date/Duration/Time) before joining","Remove the string tolerance argument, or pass a numeric tolerance matching the key dtype","Verify the join key dtypes with df.schema / df.dtypes before the join"],"exampleFix":"// before\ndf.join(other, on=\"ts\", tolerance=\"2d\")  // ts is Int64 epoch millis\n// after\ndf.with_columns(pl.col(\"ts\").cast(pl.Datetime(\"ms\")))\n  .join(other, on=\"ts\", tolerance=\"2d\")","handlingStrategy":"validation","validationCode":"schema = lf.collect_schema()\ndtype = schema[\"ts\"]\nassert dtype in (pl.Date, pl.Datetime, pl.Duration, pl.Time), f\"tolerance string requires temporal join key, got {dtype}\"","typeGuard":"def is_temporal(dtype: pl.DataType) -> bool:\n    return dtype in (pl.Date, pl.Datetime, pl.Duration, pl.Time)","tryCatchPattern":"try:\n    result = lf.join(other, on=\"ts\", tolerance=\"2d\").collect()\nexcept pl.exceptions.PanicException as e:\n    if \"timedelta string language\" in str(e):\n        result = lf.with_columns(pl.col(\"ts\").cast(pl.Datetime(\"us\"))).join(other, on=\"ts\", tolerance=\"2d\").collect()\n    else:\n        raise","preventionTips":["Check join key dtypes with collect_schema() before using string tolerance","Prefer explicit Duration/numeric tolerance over string 'timedelta language'","Cast epoch-millis integer timestamps to Datetime at ingestion"],"tags":["rust","join","dtype-mismatch","panic"],"backgroundTag":"dtype-mismatch","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}