windmill-labs/windmill · error

Unsupported asset kind for SQL parsing

Error message

Unsupported asset kind for SQL parsing

What it means

The SQL asset parser (`windmill-parser-sql-asset`) only knows how to parse SQL assets that reference DuckDB-backed connection kinds: DataTable and Ducklake. `parse_wmill_sdk_sql_assets` rejects any other `AssetKind` with this message. It is a deliberate guard, not a parse failure: those other asset kinds don't map to a DuckDB `ATTACH` prefix.

Source

Thrown at backend/parsers/windmill-parser-sql-asset/src/asset_parser_utils.rs:13

use windmill_parser::asset_parser::{AssetKind, ParseAssetsResult};

// Parse assets from sql snippets inside e.g sql`SELECT * FROM my_table`
pub fn parse_wmill_sdk_sql_assets(
    kind: AssetKind,
    asset_name: &str,
    schema: Option<&str>,
    sql: &str,
) -> anyhow::Result<Option<Vec<ParseAssetsResult>>> {
    let duckdb_conn_prefix = match kind {
        AssetKind::DataTable => "datatable",
        AssetKind::Ducklake => "ducklake",
        _ => return Err(anyhow::anyhow!("Unsupported asset kind for SQL parsing")),
    };
    let sql_with_attach =
        format!("ATTACH '{duckdb_conn_prefix}://{asset_name}' AS dt; USE dt; {sql}");

    // We use the SQL parser to detect if it's a read or write query
    match crate::parse_assets(&sql_with_attach) {
        Ok(mut sql_assets) => {
            if let Some(schema) = schema {
                for asset in &mut sql_assets.assets {
                    if asset.kind == kind && asset.path.starts_with(asset_name) {
                        asset.path = format!(
                            "{}/{}.{}",
                            asset_name,
                            schema,
                            &asset.path[asset_name.len() + 1..]
                        );
                    }
                }

View on GitHub (pinned to e474e8803c)

Solutions

  1. Filter assets to `AssetKind::DataTable` and `AssetKind::Ducklake` before calling `parse_wmill_sdk_sql_assets`.
  2. If a new AssetKind must be supported, add a `duckdb_conn_prefix` arm for it in the match at asset_parser_utils.rs:13 and rebuild.
  3. For non-SQL asset kinds, use the asset kind's own parser instead of the SQL one.

Example fix

// before
parse_wmill_sdk_sql_assets(AssetKind::S3Bucket, &asset_name, schema, sql)?

// after
match kind {
    AssetKind::DataTable | AssetKind::Ducklake => {
        parse_wmill_sdk_sql_assets(kind, &asset_name, schema, sql)?
    }
    _ => Ok(None), // handled elsewhere
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Rust: filter to supported kinds before the call
fn sql_asset_parseable(kind: AssetKind) -> bool {
    matches!(kind, AssetKind::DataTable | AssetKind::Ducklake)
}

Type guard

fn is_sql_parseable_asset(kind: &AssetKind) -> bool {
    matches!(kind, AssetKind::DataTable | AssetKind::Ducklake)
}

Try / catch

// Rust
match parse_wmill_sdk_sql_assets(kind, &name, schema, sql) {
    Ok(assets) => assets,
    Err(e) if e.to_string().contains("Unsupported asset kind") => {
        log::debug!("asset kind {kind:?} not SQL-parseable, skipping");
        None
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `parse_wmill_sdk_sql_assets` (directly or via the asset-parsing pipeline) with `kind` set to any AssetKind variant other than `DataTable` or `Ducklake` — e.g. an S3 bucket, warehouse table, or any newly added AssetKind variant that hasn't been wired into this match arm.

Common situations: A contributor adds a new AssetKind variant and forgets to extend the match in asset_parser_utils.rs; a caller iterates over all assets of a script without filtering by kind first; a refactor re-routes a non-DuckDB asset kind into the SQL asset parser by mistake.

Related errors


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