{"record":{"id":"308f7ea8132ae9c7","repo":"windmill-labs/windmill","slug":"csv-s3-input-requires-the-parquet-feature-to-be","errorCode":null,"errorMessage":"CSV S3 input requires the `parquet` feature to be enabled on this build","messagePattern":"CSV S3 input requires the `parquet` feature to be enabled on this build","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-object-store/src/lib.rs","lineNumber":1652,"sourceCode":"            .map_err(to_anyhow)?;\n\n        let mut out: Vec<u8> = Vec::new();\n        let mut writer = json::Writer::<_, JsonArray>::new(&mut out);\n        for batch in reader {\n            let batch = batch.map_err(to_anyhow)?;\n            writer.write(&batch).map_err(to_anyhow)?;\n        }\n        writer.finish().map_err(to_anyhow)?;\n        drop(writer);\n        String::from_utf8(out).map_err(to_anyhow)\n    })\n    .await\n    .map_err(to_anyhow)?\n}\n\n#[cfg(not(feature = \"parquet\"))]\npub async fn decode_csv_bytes_to_json_array(_bytes: bytes::Bytes) -> anyhow::Result<String> {\n    anyhow::bail!(\"CSV S3 input requires the `parquet` feature to be enabled on this build\")\n}\n\nlazy_static::lazy_static! {\n    pub static ref S3_PROXY_LAST_ERRORS_CACHE: Cache<String, String> = Cache::new(4);\n}\n\n#[cfg(feature = \"parquet\")]\npub async fn get_logs_from_store(\n    log_offset: i32,\n    logs: &str,\n    log_file_index: &Option<Vec<String>>,\n) -> Option<impl futures::Stream<Item = Result<bytes::Bytes, object_store::Error>>> {\n    if log_offset > 0 {\n        if let Some(file_index) = log_file_index.clone() {\n            if file_index.iter().any(|p| !is_safe_log_file_path(p)) {\n                return None;\n            }\n            if let Some(os) = get_object_store().await {","sourceCodeStart":1634,"sourceCodeEnd":1670,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-object-store/src/lib.rs#L1634-L1670","documentation":"Like the Parquet decoder, the CSV-to-JSON-array decoder for S3 file inputs lives behind the `parquet` cargo feature (it shares the blocking-thread decode infrastructure). Builds without the feature stub it out and bail with this message.","triggerScenarios":"Processing an S3 input CSV file via decode_csv_bytes_to_json_array on a backend built without the `parquet` feature.","commonSituations":"Source-compiled backends handling S3 CSV inputs; the CSV path is gated together with parquet, which surprises users who expect plain CSV support.","solutions":["Rebuild the backend with the parquet feature enabled","Use the official Windmill image with the feature included","Fetch and parse the CSV inside the script (e.g. via HTTP/S3 client) instead of using S3 file inputs"],"exampleFix":"// before\ncargo build\n// after\ncargo build --features parquet","handlingStrategy":"validation","validationCode":"// guard CSV S3 inputs on feature-less builds\nif file_extension == \"csv\" && !cfg!(feature = \"parquet\") {\n  return Err(anyhow!(\"csv s3 input needs the parquet feature in this build\"));\n}","typeGuard":null,"tryCatchPattern":"match decode_csv_bytes_to_json_array(bytes).await {\n  Err(e) if e.to_string().contains(\"CSV S3 input\") =>\n    eprintln!(\"rebuild with --features parquet or parse CSV in-script\"),\n  Err(e) => return Err(e.into()),\n  Ok(json) => json,\n}","preventionTips":["Remember CSV S3 decoding rides on the parquet feature","Enable the feature in all environments consuming S3 CSV inputs","Keep a CSV parse fallback inside the script"],"tags":["s3","csv","feature-flag","object-store"],"backgroundTag":"missing-cargo-feature","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}