{"record":{"id":"5b9a3abf366dc60a","repo":"influxdata/influxdb","slug":"unsupported-arrow-type-for-python-conversion","errorCode":null,"errorMessage":"unsupported Arrow type for Python conversion: {:?}. Supported types: Int64, UInt64, Float64, Boolean, Utf8, LargeUtf8, Timestamp(Nanosecond), Dictionary(Int32, Utf8).","messagePattern":"unsupported Arrow type for Python conversion: (.+?)\\. Supported types: Int64, UInt64, Float64, Boolean, Utf8, LargeUtf8, Timestamp\\(Nanosecond\\), Dictionary\\(Int32, Utf8\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"influxdb3_py_api/src/py_conversion.rs","lineNumber":119,"sourceCode":"            let arr = array.as_string::<i64>();\n            arr.value(index).into_pyobject(py)?.into_any().unbind()\n        }\n        DataType::Timestamp(arrow_schema::TimeUnit::Nanosecond, _) => {\n            let arr = array.as_primitive::<arrow_array::types::TimestampNanosecondType>();\n            arr.value(index).into_pyobject(py)?.into_any().unbind()\n        }\n        DataType::Dictionary(_, value_type) if value_type.as_ref() == &DataType::Utf8 => {\n            // Dictionary-encoded strings (common for tags)\n            let dict_arr = array\n                .as_any()\n                .downcast_ref::<DictionaryArray<Int32Type>>()\n                .context(\"failed to downcast dictionary array\")?;\n            let values = dict_arr.values().as_string::<i32>();\n            let key = dict_arr.keys().value(index) as usize;\n            values.value(key).into_pyobject(py)?.into_any().unbind()\n        }\n        _ => {\n            anyhow::bail!(\n                \"unsupported Arrow type for Python conversion: {:?}. \\\n                Supported types: Int64, UInt64, Float64, Boolean, Utf8, LargeUtf8, Timestamp\\\n                (Nanosecond), Dictionary(Int32, Utf8).\",\n                data_type\n            );\n        }\n    };\n\n    Ok(value)\n}\n\npub(crate) fn args_to_py_object<'py>(\n    py: Python<'py>,\n    args: &Option<HashMap<String, String>>,\n) -> PyResult<Option<Bound<'py, PyDict>>> {\n    args.as_ref()\n        .map(|args| map_to_py_object(py, args))\n        .transpose()","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/influxdata/influxdb/blob/d28e26e048401c53cbb98cf2d6ab0cf1e98048ca/influxdb3_py_api/src/py_conversion.rs#L101-L137","documentation":"py_conversion.rs converts a single Arrow value from Rust query results into a Python object for plugin code. The supported set is exactly: Int64, UInt64, Float64, Boolean, Utf8, LargeUtf8, Timestamp(Nanosecond), and Dictionary(Int32, Utf8). Any other Arrow DataType hits the catch-all arm and bails with this message, printing the offending DataType via Debug so you can see precisely which column/type failed.","triggerScenarios":"A plugin query whose output includes columns such as Timestamp(Microsecond/Millisecond/Second), Date32/Date64, Int8/16/32, Float32, Binary, or nested List/Struct types — e.g. date/time SQL functions returning non-nanosecond units, or dictionary-encoded strings keyed by something other than Int32.","commonSituations":"Using date_bin()/now()-style functions whose result unit differs from Timestamp(Nanosecond); CASTs to DATE or TIME; downstream DataFusion version changes widening the set of emitted Arrow types; selecting raw columns of exotic types from parquet.","solutions":["Read the {:?} in the message to identify the exact column type, then cast that column in SQL to a supported type (e.g. `CAST(col AS STRING)` / `::string`)","Project only the columns the plugin needs instead of SELECT *","For timestamps, normalize to nanosecond precision in the query (e.g. cast to Timestamp(Nanosecond) or string) rather than micro/millisecond units","For nested/binary data, serialize to JSON strings in SQL before it reaches the plugin"],"exampleFix":"-- before\nSELECT now() AS ts, payload FROM events\n-- Timestamp(Second/Microsecond...) can land in the unsupported arm\n\n-- after\nSELECT CAST(now() AS TIMESTAMP(9)) AS ts, CAST(payload AS STRING) AS payload FROM events","handlingStrategy":"validation","validationCode":"-- keep the plugin-facing projection inside the supported type set\nSELECT\n  CAST(ts AS TIMESTAMP(9))  AS ts,          -- Timestamp(Nanosecond)\n  CAST(id AS BIGINT)         AS id,          -- Int64\n  CAST(payload AS STRING)    AS payload      -- Utf8\nFROM events;","typeGuard":null,"tryCatchPattern":"match run_plugin_query(&sql).await {\n    Err(e) if e.to_string().contains(\"unsupported Arrow type\") => {\n        // ask the user to cast the reported column; the message names the exact DataType\n        Err(reject_with_hint(e, \"cast the reported column to Int64/UInt64/Float64/Boolean/Utf8/LargeUtf8/Timestamp(Nanosecond)/Dictionary(Int32, Utf8)\"))\n    }\n    other => other,\n}","preventionTips":["Avoid SELECT * in plugin queries; project and cast columns explicitly","Normalize timestamps to nanosecond precision in SQL before they cross into Python","Watch the {:?} in the message — it names the exact offending Arrow type"],"tags":["influxdb","arrow","python","type-conversion","processing-engine","pyo3"],"backgroundTag":"unsupported-type-conversion","analyzedSha":"d28e26e048401c53cbb98cf2d6ab0cf1e98048ca","analyzedAt":"2026-08-16T19:53:34.623Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}