apache/superset · error · QueryObjectValidationError
Columns missing in dataset: %(invalid_columns)s
Error message
Columns missing in dataset: %(invalid_columns)s
What it means
QueryContextProcessor.get_payload (cache-key path) verifies that every column in query_obj.columns plus every metric name exists in the datasource's column_names (DTTM_ALIAS excepted). Any unknown name collects into invalid_columns and raises QueryObjectValidationError('Columns missing in dataset: ...').
Source
Thrown at superset/common/query_context_processor.py:146
):
cache.is_loaded = False
cache_resolution_ns = max(0, time.perf_counter_ns() - cache_resolution_start_ns)
data_acquisition_ns: int | None = None
if query_obj and cache_key and not cache.is_loaded:
data_acquisition_start_ns = time.perf_counter_ns()
try:
if invalid_columns := [
col
for col in get_column_names_from_columns(query_obj.columns)
+ get_column_names_from_metrics(query_obj.metrics or [])
if (
col not in self._qc_datasource.column_names
and col != DTTM_ALIAS
)
]:
raise QueryObjectValidationError(
_(
"Columns missing in dataset: %(invalid_columns)s",
invalid_columns=invalid_columns,
)
)
query_result = self.get_query_result(query_obj)
annotation_data = self.get_annotation_data(query_obj)
except QueryObjectValidationError as ex:
cache.error_message = str(ex)
cache.status = QueryStatus.FAILED
finally:
data_acquisition_ns = max(
0, time.perf_counter_ns() - data_acquisition_start_ns
)
if cache.status != QueryStatus.FAILED:
cache.set_query_result(View on GitHub (pinned to f4587218dd)
Solutions
- Sync the dataset: refresh columns in the dataset editor (or via API) so it matches the physical schema.
- Update the chart's controls/params to use current column names.
- If the column exists in the DB but not the dataset, add it to the dataset metadata.
Example fix
# before
{"columns": ["user_nm"], ...} # dataset has user_name
# after
{"columns": ["user_name"], ...} # match dataset column_names Defensive patterns
Strategy: validation
Validate before calling
valid = set(datasource.column_names) | {"__timestamp"}
invalid = [c for c in requested_columns if c not in valid]
if invalid:
raise ValueError(f"unknown columns: {invalid}") Type guard
def columns_exist(ds, cols: list[str]) -> bool:
names = set(ds.column_names)
return all(c in names or c == "__timestamp" for c in cols) Try / catch
except QueryObjectValidationError as e:
if "Columns missing in dataset" in str(e):
sync_dataset_columns(); resubmit() Prevention
- Refresh dataset metadata after schema changes
- Validate chart params against dataset before API calls
When it happens
Trigger: POSTing a chart data request whose columns/metrics reference fields not present on the dataset — renamed or dropped DB columns, a stale chart payload after dataset changes, or a query context built against a different dataset.
Common situations: Underlying table schema changed (column renamed/dropped) while charts still request the old names; chart JSON copied to a different dataset; caching layer bypassed so the validation runs against current schema.
Related errors
- Datasource does not exist
- Drill to detail is not available for this datasource type.
- Invalid result type: %(result_type)s
- Dataset parameters are invalid.
- Dataset parameters are invalid.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/2a18368216e28767.
Report an issue: GitHub.