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
- Filter assets to `AssetKind::DataTable` and `AssetKind::Ducklake` before calling `parse_wmill_sdk_sql_assets`.
- 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.
- 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
- Route assets to the SQL parser only after checking kind in {DataTable, Ducklake}.
- When adding a new AssetKind variant, run a match-exhaustiveness check and update this parser in the same PR.
- Treat non-DuckDB asset kinds with their own parsers, never the SQL one.
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
- Failed to get Ducklake schema: <json of result>
- no policy could be derived for runnable(s) ${malformed.join(
- result.substring(__RESULT_ERR_PREFIX.length)
- Local PathScript ${filePath} requires codebase assets, which
- Error parsing yaml ${path}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/bdfded76713f7093.
Report an issue: GitHub.