apache/superset · error · QueryObjectValidationError
The following entries in `series_columns` are missing in `co
Error message
The following entries in `series_columns` are missing in `columns`: %(columns)s.
What it means
QueryObjectValidationError raised by QueryObject._validate_there_are_no_missing_series when one or more names listed in series_columns do not appear in the query object's columns list. Superset requires every series (groupby/dimension used for series limiting or sequencing) to also be part of the selected columns so the generated SQL can actually project them. It is a client-side consistency check that fires before any SQL is issued.
Source
Thrown at superset/common/query_object.py:386
# source_engine=engine ensures idempotency: this
# method can run more than once (validate() is called
# from both raise_for_access and get_df_payload), so
# the second pass must be able to re-parse the
# dialect-specific output (e.g. BigQuery backticks)
# produced by the first pass.
clause = transpile_to_dialect(
clause, engine, source_engine=engine, identify=True
)
sanitized_clause = sanitize_clause(clause, engine)
self.extras[param] = sanitized_clause
except QueryClauseValidationException as ex:
raise QueryObjectValidationError(ex.message) from ex
def _validate_there_are_no_missing_series(self) -> None:
missing_series = [col for col in self.series_columns if col not in self.columns]
if missing_series:
raise QueryObjectValidationError(
_(
"The following entries in `series_columns` are missing "
"in `columns`: %(columns)s. ",
columns=", ".join(f'"{x}"' for x in missing_series),
)
)
def to_dict(self) -> QueryObjectDict:
query_object_dict: QueryObjectDict = {
"apply_fetch_values_predicate": self.apply_fetch_values_predicate,
"columns": self.columns,
"extras": self.extras,
"filter": self.filter,
"from_dttm": self.from_dttm,
"granularity": self.granularity,
"inner_from_dttm": self.inner_from_dttm,
"inner_to_dttm": self.inner_to_dttm,
"is_rowcount": self.is_rowcount,View on GitHub (pinned to f4587218dd)
Solutions
- Inspect the query payload and add every missing series_columns entry to the columns (groupby) list of the same query object.
- If the series column no longer exists in the dataset, remove or rename it in series_columns to match the current dataset schema.
- For chart plugins, ensure the transformFormData logic copies the same field into both groupby and series_columns.
- Run the query through /api/v1/chart/data with a minimal payload after fixing to confirm validation passes.
Example fix
// before
const queryObject = {
columns: ['country'],
series_columns: ['country', 'region'], // 'region' missing from columns
metrics: ['sum__sales'],
};
// after
const queryObject = {
columns: ['country', 'region'], // every series column is projected
series_columns: ['country', 'region'],
metrics: ['sum__sales'],
}; Defensive patterns
Strategy: validation
Validate before calling
def validate_series_in_columns(query_object: dict) -> None:
columns = set(query_object.get("columns") or [])
missing = [c for c in (query_object.get("series_columns") or []) if c not in columns]
if missing:
raise ValueError(f"series_columns not in columns: {missing}") Try / catch
from superset.common.query_object import QueryObject
from superset.exceptions import QueryObjectValidationError
try:
qo = QueryObject(**params)
except QueryObjectValidationError as ex:
if "series_columns" in str(ex):
params["columns"] = list(set(params.get("columns", [])) | set(params.get("series_columns", [])))
qo = QueryObject(**params)
else:
raise Prevention
- Derive series_columns from the same source array as columns/groupby in chart plugins.
- Add a unit test asserting set(series_columns) <= set(columns) for generated query payloads.
- After renaming dataset columns, run a dashboard chart smoke test to catch stale references.
When it happens
Trigger: Building a QueryContext/QueryObject payload (e.g. via chart REST API /api/v1/chart/data or programmatically via superset.common.QueryObject) where series_columns contains a column name that is absent from columns. Typical with custom chart plugins or hand-crafted FormData that set series_columns independently of groupby/columns.
Common situations: Custom viz plugins that add series_columns without mirroring them into groupby; renames of a dataset column where the chart definition still stores the old name in series metadata; programmatic query generation that derives series_columns from a different source than columns.
Related errors
- Unsupported whisker type: ${whiskerOptions}
- Found invalid orderby options
- Unknown Error
- Please provide both time bounds (Since and Until)
- All values must be numeric
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/fda55e8584b57756.
Report an issue: GitHub.