{"record":{"id":"d8e100318ca4fcfc","repo":"pola-rs/polars","slug":"invalid-time-unit-tu-for-duration","errorCode":null,"errorMessage":"Invalid time unit '{tu:?}' for Duration.","messagePattern":"Invalid time unit '(.+?)' for Duration\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-json/src/json/write/serialize.rs","lineNumber":612,"sourceCode":"                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,\n                TimeUnit::Microsecond => duration_us_to_duration,\n                TimeUnit::Millisecond => duration_ms_to_duration,\n                tu => panic!(\"Invalid time unit '{tu:?}' for Duration.\"),\n            };\n            duration_serializer(\n                array.as_any().downcast_ref().unwrap(),\n                convert,\n                offset,\n                take,\n            )\n        },\n        ArrowDataType::Time64(tu) => {\n            let convert = match tu {\n                TimeUnit::Nanosecond => time64ns_to_time,\n                tu => panic!(\"Invalid time unit '{tu:?}' for Time.\"),\n            };\n            time_serializer(\n                array.as_any().downcast_ref().unwrap(),\n                convert,\n                offset,\n                take,","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/pola-rs/polars/blob/9b5d73fd00236295624374b075d16b1fe6ec6df9/crates/polars-json/src/json/write/serialize.rs#L594-L630","documentation":"The Duration branch of the JSON serializer has converters only for Nanosecond/Microsecond/Millisecond; Duration(TimeUnit::Second) - legal in Arrow - hits the catch-all panic. Second-precision durations typically enter via arrow-rs interop or hand-constructed arrays.","triggerScenarios":"write_json on a column typed ArrowDataType::Duration(TimeUnit::Second), e.g. an arrow-rs array built with DurationSecondType or converted from ISO-8601 'PT5S' values.","commonSituations":"arrow-rs interop; pipelines that normalized durations to seconds for storage.","solutions":["Cast to Duration(Milliseconds) (or us/ns) before write_json","Or store as Int64 seconds and format units yourself","Validate the dtype list before exporting JSON"],"exampleFix":"// before: column typed Duration(Second)\ndf.write_json(&mut out)?; // panic: Invalid time unit 'Second' for Duration.\n\n// after\nlet df = df.with_column(col(\"d\").cast(&DataType::Duration(TimeUnit::Milliseconds)))?;\ndf.write_json(&mut out)?;","handlingStrategy":"fallback","validationCode":"fn normalize_duration_units(df: &DataFrame) -> PolarsResult<DataFrame> {\n    let mut exprs = vec![];\n    for (name, dt) in df.schema().iter() {\n        if matches!(dt, DataType::Duration(TimeUnit::Seconds)) {\n            exprs.push(col(name).cast(&DataType::Duration(TimeUnit::Milliseconds)).alias(name));\n        }\n    }\n    df.lazy().with_columns(exprs).collect()\n}\n// run before write_json","typeGuard":"fn has_writable_duration_units(df: &DataFrame) -> bool {\n    df.schema().iter_values().all(|dt| match dt {\n        DataType::Duration(tu) => !matches!(tu, TimeUnit::Seconds),\n        _ => true,\n    })\n}","tryCatchPattern":"catch_unwind around the write to convert the panic into a clean export error; casting Duration(Second) -> Duration(Milliseconds) beforehand is the durable fix.","preventionTips":["Convert second-precision durations to ms/us/ns at ingestion","Check dtypes in a pre-export validation pass","Cover every duration unit in export fixtures"],"tags":["polars","json","duration","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-14T05:17:10.506Z"}