windmill-labs/windmill · error

Invalid S3 mode format

Error message

Invalid S3 mode format: {}

What it means

windmill-parser-sql parses S3 mode options passed to SQL scripts (e.g. `s3://...?prefix=x&storage=y&format=csv` style key-value pairs). parse_s3_mode accepts only format values json, parquet, or csv; any other format value makes the parser fail fast with this message so the invalid S3 config never reaches job execution.

Solutions

  1. Change the format value to one of json, parquet, or csv
  2. Check for case mismatches — the match is lowercase-exact
  3. If you need another format, it is unsupported by the parser; use one of the three supported ones

Example fix

// before
s3mode=prefix=/data,storage=s3,format=avro
// after
s3mode=prefix=/data,storage=s3,format=parquet
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = new Set(['json', 'parquet', 'csv']);
function validateS3ModeFormat(format) {
  if (!SUPPORTED.has(format)) throw new Error(`Invalid S3 mode format: ${format}. Use json, parquet, or csv.`);
}
validateS3ModeFormat('parquet'); // call before deploy/parse

Type guard

function isS3ModeFormat(v) { return v === 'json' || v === 'parquet' || v === 'csv'; }

Try / catch

try {
  parseSqlWithS3Mode(script);
} catch (e) {
  if (String(e).includes('Invalid S3 mode format')) {
    // surface a config-validation message to the user
  } else throw e;
}

Prevention

When it happens

Trigger: Calling any SQL parse entrypoint (do_bigquery, do_mssql, do_mysql, do_oracledb, do_postgresql, do_snowflake) with an S3 mode argument whose `format` key has a value outside {json, parquet, csv}, e.g. `format=avro` or `format=JSON` (case-sensitive).

Common situations: Typos in format names, uppercase/lowercase mismatch, copying configs from other tools that support more formats (avro, orc), or hand-editing a script's S3 settings in the UI YAML.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/b6f7fb973d5f22d7. Report an issue: GitHub.

Appendix: source

Thrown at backend/parsers/windmill-parser-sql/src/lib.rs:188

    let mut prefix = None;
    let mut storage = None;
    let mut format = S3ModeFormat::Json;

    for kv in args_str.split(' ').map(|kv| kv.trim()) {
        if kv.is_empty() {
            continue;
        }
        let mut it = kv.split('=');
        let (Some(key), Some(value)) = (it.next(), it.next()) else {
            return Err(anyhow!("Invalid S3 mode argument: {}", kv));
        };
        match (key.trim(), value.trim()) {
            ("prefix", _) => prefix = Some(value.to_string()),
            ("storage", _) => storage = Some(value.to_string()),
            ("format", "json") => format = S3ModeFormat::Json,
            ("format", "parquet") => format = S3ModeFormat::Parquet,
            ("format", "csv") => format = S3ModeFormat::Csv,
            ("format", format) => return Err(anyhow!("Invalid S3 mode format: {}", format)),
            (_, _) => return Err(anyhow!("Invalid S3 mode argument: {}", kv)),
        }
    }

    Ok(Some(S3ModeArgs { prefix, storage, format }))
}

pub fn parse_sql_blocks(code: &str, track_dollar_quotes: bool) -> Vec<&str> {
    let mut blocks = vec![];
    let mut last_idx = 0;

    run_on_sql_statement_matches(
        code,
        track_dollar_quotes,
        |char, _| char == ';',
        |idx, _| {
            blocks.push(&code[last_idx..=idx]);
            last_idx = idx + 1;

View on GitHub (pinned to e474e8803c)