{"record":{"id":"b02597f7cb284b08","repo":"pola-rs/polars","slug":"activate-one-of-dtype-date-dtype-datetime","errorCode":null,"errorMessage":"activate one of {{'dtype-date', 'dtype-datetime', dtype-time'}} features","messagePattern":"activate one of (.+?)\\} features","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-io/src/csv/read/schema_inference.rs","lineNumber":353,"sourceCode":"            #[cfg(feature = \"polars-time\")]\n            {\n                match date_infer::infer_pattern_single(&string[1..string.len() - 1]) {\n                    Some(pattern_with_offset) => match pattern_with_offset {\n                        Pattern::DatetimeYMD | Pattern::DatetimeDMY => {\n                            DataType::Datetime(TimeUnit::Microseconds, None)\n                        },\n                        Pattern::DateYMD | Pattern::DateDMY => DataType::Date,\n                        Pattern::DatetimeYMDZ => {\n                            DataType::Datetime(TimeUnit::Microseconds, Some(TimeZone::UTC))\n                        },\n                        Pattern::Time => DataType::Time,\n                    },\n                    None => DataType::String,\n                }\n            }\n            #[cfg(not(feature = \"polars-time\"))]\n            {\n                panic!(\"activate one of {{'dtype-date', 'dtype-datetime', dtype-time'}} features\")\n            }\n        } else {\n            DataType::String\n        }\n    }\n    // match regex in a particular order\n    else if BOOLEAN_RE.is_match(string) {\n        DataType::Boolean\n    } else if !decimal_comma && FLOAT_RE.is_match(string)\n        || decimal_comma && FLOAT_RE_DECIMAL.is_match(string)\n    {\n        DataType::Float64\n    } else if INTEGER_RE.is_match(string) {\n        if string.parse::<i64>().is_ok() {\n            DataType::Int64\n        } else {\n            #[cfg(feature = \"dtype-i128\")]\n            {","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/pola-rs/polars/blob/5d8ebabf11caea54a5c29178a64a058762f49766/crates/polars-io/src/csv/read/schema_inference.rs#L335-L371","documentation":"infer_field_schema() converts date/time-looking CSV fields to Date/Datetime/Time dtypes, but only when the polars-time crate is compiled in - enabled via the dtype-date, dtype-datetime or dtype-time cargo features. In a build with none of them, the cfg(not(feature = \"polars-time\")) arm panics as soon as try_parse_dates is on and a quoted value reaches this branch (this is the quoted-field branch at line 330). Python builds always ship these features; only custom Rust builds can hit it.","triggerScenarios":"read_csv with try_parse_dates=true (or any code path calling infer_field_schema) on a file whose quoted values look temporal (e.g. \"\\\"2024-01-31\\\"\"), in a crate built with polars-io default-features=false and none of the dtype-date/dtype-datetime/dtype-time features.","commonSituations":"Slimming a Rust binary by trimming polars features; losing feature unification from a transitive dependency after an upgrade; porting working code from the python wheel (features always on) to a Rust service.","solutions":["Add the features in Cargo.toml: polars-io = { version = \"...\", default-features = false, features = [\"dtype-date\", \"dtype-datetime\", \"dtype-time\"] } (or enable polars-time)","If you depend on the umbrella polars crate, enable the same-named features there - they are additive and flow down","Workaround: pass an explicit schema typing those columns as String, or set try_parse_dates=false, so inference never enters the temporal branch"],"exampleFix":"# before\npolars-io = { version = \"0.4\", default-features = false }\n\n# after\npolars-io = { version = \"0.4\", default-features = false, features = [\n  \"dtype-date\", \"dtype-datetime\", \"dtype-time\",\n] }","handlingStrategy":"validation","validationCode":"use polars_io::prelude::*;\nuse std::io::Cursor;\n\nfn csv_temporal_inference_available() -> bool {\n    // If the polars-time feature is off, date-like inference panics.\n    // Probe once, cheaply, at startup:\n    std::panic::catch_unwind(|| {\n        let src = Cursor::new(b\"d\\n2024-01-31\\n\");\n        CsvReader::new(src).with_try_parse_dates(true).finish()\n    })\n    .is_ok()\n}\n// if false -> fail startup with 'rebuild polars-io with dtype-date/dtype-datetime/dtype-time'","typeGuard":null,"tryCatchPattern":"The panic is deterministic (missing compile-time feature): catch_unwind(AssertUnwindSafe(|| reader.finish())) can only downgrade it to an error message; the durable fix is Cargo features, not catching.","preventionTips":["Keep the temporal dtype-* features in one shared workspace feature so they cannot be dropped selectively","Add a CSV fixture containing dates to CI so a missing feature fails in CI, not production","Enable features on the top-level polars crate so they unify with what the CSV path needs"],"tags":["polars","csv","schema-inference","cargo-features","build-configuration","panic"],"backgroundTag":"missing-cargo-feature","analyzedSha":"5d8ebabf11caea54a5c29178a64a058762f49766","analyzedAt":"2026-08-19T12:15:06.350Z","contentChangedAt":"2026-08-19T12:15:06.350Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}