apache/superset · error · SupersetGenericDBErrorException
Virtual dataset query cannot be empty
Error message
Virtual dataset query cannot be empty
What it means
SupersetGenericDBErrorException raised in get_virtual_table_metadata (utils.py:109) when a dataset flagged as virtual has an empty/None sql attribute. Virtual datasets are defined entirely by their SQL; with no SQL there is nothing to parse or execute, so metadata retrieval fails immediately before template processing.
Source
Thrown at superset/connectors/sqla/utils.py:109
col.update(
{
"type": "UNKNOWN",
"type_generic": None,
"is_dttm": None,
}
)
return cols
def _has_jinja_markers(sql: str) -> bool:
"""Return True if ``sql`` contains Jinja template markers (``{%`` or ``{{``)."""
return "{%" in sql or "{{" in sql
def get_virtual_table_metadata(dataset: SqlaTable) -> list[ResultSetColumnType]:
"""Use SQLparser to get virtual dataset metadata"""
if not dataset.sql:
raise SupersetGenericDBErrorException(
message=_("Virtual dataset query cannot be empty"),
)
db_engine_spec = dataset.database.db_engine_spec
original_sql = dataset.sql
try:
sql = dataset.get_template_processor().process_template(
original_sql, **dataset.template_params_dict
)
except SupersetSyntaxErrorException as ex:
# ``process_template`` aggregates several jinja2 exceptions
# (``TemplateSyntaxError``, ``SecurityError``, ``UndefinedError``,
# ``Unicode*Error``) into ``SupersetSyntaxErrorException``. Only
# the ``UndefinedError`` case is a "missing runtime context"
# signal that ``RefreshDatasetCommand`` can safely soften — the
# rest (sandbox violations, malformed template syntax, encoding
# errors) indicate a real problem with the template that must
# surface. See #38012.View on GitHub (pinned to f4587218dd)
Solutions
- Open the dataset in the editor and provide the virtual dataset's SQL query, then save.
- If the dataset should be physical, set its kind to physical (table-based) with correct table_name/schema instead of leaving an empty virtual definition.
- Audit for other broken rows: SELECT id, table_name FROM tables WHERE kind='virtual' AND (sql IS NULL OR sql='');
Example fix
# before Dataset(kind='virtual', table_name='my_vds', sql=None) # after Dataset(kind='virtual', table_name='my_vds', sql='SELECT id, amt FROM sales WHERE amt > 0')
Defensive patterns
Strategy: validation
Validate before calling
def validate_virtual_dataset(dataset) -> None:
if getattr(dataset, "kind", None) == "virtual" and not (dataset.sql or "").strip():
raise ValueError("virtual dataset requires a non-empty sql query") Type guard
def is_complete_virtual_dataset(dataset: object) -> bool:
return not (getattr(dataset, "kind", "") == "virtual" and not (getattr(dataset, "sql", None) or "").strip()) Try / catch
from superset.exceptions import SupersetGenericDBErrorException
try:
cols = get_virtual_table_metadata(dataset)
except SupersetGenericDBErrorException as ex:
if "cannot be empty" in str(ex):
raise ValueError(f"Dataset {dataset.id} is virtual but has no SQL; fix in dataset editor") from ex
raise Prevention
- Enforce non-empty sql in dataset creation APIs and import tooling.
- Periodically audit: SELECT id FROM tables WHERE kind='virtual' AND (sql IS NULL OR sql='').
- Treat empty-SQL virtual datasets as import defects and reject them in CI.
When it happens
Trigger: Saving a dataset with kind='virtual' (or sql null/blank) — e.g. the UI allowed creating a virtual dataset without SQL, an import/migration produced one, or a script created the row directly. Any operation needing metadata (Explore, chart data, dataset list) triggers it.
Common situations: Dataset YAML import with missing sql field; API-created datasets omitting sql; datasets whose SQL was cleared during editing; migration scripts copying dataset rows incompletely.
Related errors
- Dataset parameters are invalid.
- Dataset parameters are invalid.
- Dataset parameters are invalid.
- Cycle detected: {uuid} appears in its ancestry
- Duplicate UUID in folder structure: {uuid}
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/742129a05d5f85eb.
Report an issue: GitHub.