{"record":{"id":"23c3bb98bea4ff48","repo":"pola-rs/polars","slug":"invalid-time-unit-tu-for-datetime","errorCode":null,"errorMessage":"Invalid time unit '{tu:?}' for Datetime.","messagePattern":"Invalid time unit '(.+?)' for Datetime\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-json/src/json/write/serialize.rs","lineNumber":591,"sourceCode":"                dictionary_utf8view_serializer::<u32>(array, offset, take)\n            },\n            _ => {\n                // Not produced by polars\n                unreachable!()\n            },\n        },\n        ArrowDataType::Date32 => date_serializer(\n            array.as_any().downcast_ref().unwrap(),\n            date32_to_date,\n            offset,\n            take,\n        ),\n        ArrowDataType::Timestamp(tu, None) => {\n            let convert = match tu {\n                TimeUnit::Nanosecond => timestamp_ns_to_datetime,\n                TimeUnit::Microsecond => timestamp_us_to_datetime,\n                TimeUnit::Millisecond => timestamp_ms_to_datetime,\n                tu => panic!(\"Invalid time unit '{tu:?}' for Datetime.\"),\n            };\n            timestamp_serializer(\n                array.as_any().downcast_ref().unwrap(),\n                convert,\n                offset,\n                take,\n            )\n        },\n        ArrowDataType::Timestamp(time_unit, Some(tz)) => timestamp_tz_serializer(\n            array.as_any().downcast_ref().unwrap(),\n            *time_unit,\n            tz,\n            offset,\n            take,\n        ),\n        ArrowDataType::Duration(tu) => {\n            let convert = match tu {\n                TimeUnit::Nanosecond => duration_ns_to_duration,","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/pola-rs/polars/blob/9b5d73fd00236295624374b075d16b1fe6ec6df9/crates/polars-json/src/json/write/serialize.rs#L573-L609","documentation":"The JSON writer maps naive Timestamp columns to chrono converters only for Nanosecond, Microsecond and Millisecond units. Timestamp(TimeUnit::Second, None) - legal in Arrow and typical of arrow-rs interop - falls through to the catch-all panic. Second-with-tz goes down timestamp_tz_serializer instead, so this is specifically the naive path.","triggerScenarios":"write_json on an Int64 array typed ArrowDataType::Timestamp(TimeUnit::Second, None): data converted from arrow-rs RecordBatches, IPC/Avro readers, or hand-built arrays using second-precision epoch values.","commonSituations":"arrow-rs/polars interop boundaries; datasets produced by systems that store epoch-seconds.","solutions":["Cast to a supported unit before writing: df.cast / with_column(col(\"ts\").cast(&DataType::Datetime(TimeUnit::Microseconds, None)))","If building arrays yourself, encode timestamps in us/ms/ns rather than s","Inspect dtypes (schema) before write_json and normalize units"],"exampleFix":"// before: column typed Timestamp(Second, None)\ndf.write_json(&mut out)?; // panic: Invalid time unit 'Second' for Datetime.\n\n// after\nlet df = df.with_column(col(\"ts\").cast(&DataType::Datetime(TimeUnit::Microseconds, None)))?;\ndf.write_json(&mut out)?;","handlingStrategy":"fallback","validationCode":"fn normalize_timestamp_units(df: &DataFrame) -> PolarsResult<DataFrame> {\n    let mut exprs = vec![];\n    for (name, dt) in df.schema().iter() {\n        if matches!(dt, DataType::Datetime(TimeUnit::Seconds, _)) {\n            exprs.push(col(name).cast(&DataType::Datetime(TimeUnit::Microseconds, dt.time_zone().cloned())).alias(name));\n        }\n    }\n    df.lazy().with_columns(exprs).collect()\n}\n// run before write_json / JsonWriter::write","typeGuard":"fn has_writable_timestamp_units(df: &DataFrame) -> bool {\n    df.schema().iter_values().all(|dt| match dt {\n        DataType::Datetime(tu, _) => !matches!(tu, TimeUnit::Seconds),\n        _ => true,\n    })\n}","tryCatchPattern":"catch_unwind(AssertUnwindSafe(|| df.write_json(&mut out))) to get a job-level error; casting Seconds -> Microseconds beforehand removes the failing branch entirely.","preventionTips":["Cast Timestamp(Second) to us/ms/ns at every arrow interop boundary","Assert on dtypes before JSON export in tests","Document that polars' JSON writer supports only ns/us/ms timestamps"],"tags":["polars","json","datetime","time-unit","arrow","serialization","panic"],"backgroundTag":"unsupported-time-unit","analyzedSha":"9b5d73fd00236295624374b075d16b1fe6ec6df9","analyzedAt":"2026-08-19T12:15:06.350Z","contentChangedAt":"2026-08-19T12:15:06.350Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}