{"record":{"id":"7428141737b476de","repo":"pola-rs/polars","slug":"creating-extension-types-not-allowed-try-setting-the","errorCode":null,"errorMessage":"creating extension types not allowed - try setting the environment variable POLARS_ALLOW_EXTENSION","messagePattern":"creating extension types not allowed - try setting the environment variable POLARS_ALLOW_EXTENSION","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-core/src/chunked_array/object/extension/mod.rs","lineNumber":69,"sourceCode":"            (drop_fn)()\n        }\n    }\n}\n\n// https://stackoverflow.com/questions/28127165/how-to-convert-struct-to-u8d\n// not entirely sure if padding bytes in T are initialized or not.\nunsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {\n    std::slice::from_raw_parts((p as *const T) as *const u8, size_of::<T>())\n}\n\n/// Create an extension Array that can be sent to arrow and (once wrapped in [`PolarsExtension`] will\n/// also call drop on `T`, when the array is dropped.\npub(crate) fn create_extension<I: Iterator<Item = Option<T>> + TrustedLen, T: Sized + Default>(\n    iter: I,\n) -> PolarsExtension {\n    let env = \"POLARS_ALLOW_EXTENSION\";\n    if !(POLARS_ALLOW_EXTENSION.load() || std::env::var(env).is_ok()) {\n        panic!(\"creating extension types not allowed - try setting the environment variable {env}\")\n    }\n    let t_size = size_of::<T>();\n    let t_alignment = align_of::<T>();\n    let n_t_vals = iter.size_hint().1.unwrap();\n\n    let mut buf = Vec::with_capacity(n_t_vals * t_size);\n    let mut validity = BitmapBuilder::with_capacity(n_t_vals);\n\n    // when we transmute from &[u8] to T, T must be aligned correctly,\n    // so we pad with bytes until the alignment matches\n    let n_padding = (buf.as_ptr() as usize) % t_alignment;\n    buf.extend(std::iter::repeat_n(0, n_padding));\n\n    // transmute T as bytes and copy in buffer\n    for opt_t in iter.into_iter() {\n        match opt_t {\n            Some(t) => {\n                unsafe {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-core/src/chunked_array/object/extension/mod.rs#L51-L87","documentation":"Polars' Object/extension dtype stores arbitrary Rust values in an Arrow ExtensionArray. Because the on-disk/FFI layout of extension arrays is not guaranteed stable, creating them is gated behind an explicit opt-in: either the POLARS_ALLOW_EXTENSION environment variable is set or the POLARS_ALLOW_EXTENSION feature gate was compiled in. Without it, create_extension panics to prevent users from unknowingly producing data with unsafe/unsupported semantics.","triggerScenarios":"Any API that builds an ObjectChunked / PolarsExtension, e.g. calling agg_list or finish on a Series/ObjectChunked of a custom Rust type (via #[derive(PolarsObject)] types) while neither the compiled-in POLARS_ALLOW_EXTENSION flag nor the env var is present.","commonSituations":"Using polars' object dtype feature with custom structs in GroupBy aggregations, or after upgrading polars where the opt-in became mandatory; running in environments (tests, containers) where the env var was never set.","solutions":["Set the environment variable POLARS_ALLOW_EXTENSION=1 before running the program to opt in to extension type creation","If you control the build, enable the compile-time POLARS_ALLOW_EXTENSION flag instead of the env var","Avoid the object/extension dtype entirely and model the data with supported dtypes (struct, list, string)"],"exampleFix":"// before\nlet out = df.group_by([\"k\"])?.agg([col(\"obj\").agg_list()]); // panics\n// after\n// in shell / process env:\nstd::env::set_var(\"POLARS_ALLOW_EXTENSION\", \"1\");\nlet out = df.group_by([\"k\"])?.agg([col(\"obj\").agg_list()]);","handlingStrategy":"validation","validationCode":"if std::env::var(\"POLARS_ALLOW_EXTENSION\").is_err() {\n    std::env::set_var(\"POLARS_ALLOW_EXTENSION\", \"1\"); // or avoid object dtype\n}","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| build_object_series());","preventionTips":["Set POLARS_ALLOW_EXTENSION early in process bootstrap when using the object feature","Prefer struct dtype over object dtype for new code","Document the env var requirement in any team/container config"],"tags":["rust","polars","object-dtype","environment-variable"],"backgroundTag":"missing-env-var","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"}