apache/superset · error · QueryObjectValidationError
Adhoc metric expressionType is invalid
Error message
Adhoc metric expressionType is invalid
What it means
QueryObjectValidationError raised in SqlaTable.adhoc_metric_to_sqla (models.py:1931) when the adhoc metric's expressionType is neither 'SIMPLE' nor 'SQL'. Superset dispatches metric construction on this discriminator; any other value (typo, null, legacy value) falls to the else branch. Note this raise is the one place without _() translation, but the semantics are identical.
Source
Thrown at superset/connectors/sqla/models.py:1931
raise QueryObjectValidationError(
_("Adhoc metric SQL expression is invalid")
)
if not processed:
try:
expression = self._process_select_expression(
expression=expression,
database_id=self.database_id,
engine=self.database.backend,
schema=self.schema,
template_processor=template_processor,
)
except SupersetSecurityException as ex:
raise QueryObjectValidationError(ex.message) from ex
sqla_metric = literal_column(expression)
else:
raise QueryObjectValidationError("Adhoc metric expressionType is invalid")
return self.make_sqla_column_compatible(sqla_metric, label)
def _render_adhoc_expression_for_metadata_lookup(
self,
sql_expression: str,
template_processor: BaseTemplateProcessor | None,
) -> str:
"""Render Jinja in *sql_expression* so the result can be matched against
column metadata. Without this, a templated expression such as
``{{ filter_values('x')[0] }}`` is passed raw to ``get_column``, never
matches, and falls back to ``literal_column`` — which breaks for virtual
datasets because the rendered name isn't present in the FROM subquery."""
if not template_processor:
return sql_expression
try:
return template_processor.process_template(sql_expression)
except SupersetSyntaxErrorException as ex:View on GitHub (pinned to f4587218dd)
Solutions
- Set expressionType to exactly 'SIMPLE' or 'SQL' (see superset/common/utils/query_utils.py AdhocMetricExpressionType).
- For simple aggregation: provide column + aggregate; for SQL: provide sqlExpression.
- Re-create the metric through the Explore UI to get canonical JSON.
Example fix
// before
{ expressionType: 'simple', column: { column_name: 'sales' }, aggregate: 'SUM' }
// after
{ expressionType: 'SIMPLE', column: { column_name: 'sales' }, aggregate: 'SUM' } Defensive patterns
Strategy: type-guard
Validate before calling
VALID_EXPRESSION_TYPES = {"SIMPLE", "SQL"}
def validate_metric_shape(metric: dict) -> None:
et = metric.get("expressionType")
if et not in VALID_EXPRESSION_TYPES:
raise ValueError(f"expressionType must be one of {VALID_EXPRESSION_TYPES}, got {et!r}") Type guard
from typing import TypedDict, Literal, NotRequired
class AdhocMetric(TypedDict):
expressionType: Literal["SIMPLE", "SQL"]
column: NotRequired[dict]
aggregate: NotRequired[str]
sqlExpression: NotRequired[str]
def is_adhoc_metric_typed(metric: object) -> bool:
return (
isinstance(metric, dict)
and metric.get("expressionType") in {"SIMPLE", "SQL"}
) Try / catch
from superset.exceptions import QueryObjectValidationError
try:
col = table.adhoc_metric_to_sqla(metric, columns_by_name)
except QueryObjectValidationError as ex:
if "expressionType is invalid" in str(ex):
metric = {**metric, "expressionType": metric.get("expressionType", "").upper()}
col = table.adhoc_metric_to_sqla(metric, columns_by_name)
else:
raise Prevention
- Use the AdhocMetricExpressionType enum values verbatim; never lowercase variants.
- Type chart formData metric fields in TypeScript with a discriminated union.
- Re-save imported dashboards in Explore to normalize metric JSON.
When it happens
Trigger: Adhoc metric dict like {expressionType: 'simple' | 'Custom' | null | 'Api'}, or a payload from a different Superset version/plugin using an unsupported expressionType enum value.
Common situations: Case mismatch ('simple' vs 'SIMPLE') from hand-written payloads; dashboard/chart export-import between versions whose AdhocMetricExpressionType enum differs; custom chart plugins emitting their own metric shapes.
Related errors
- Adhoc metric aggregate is invalid
- Adhoc metric SQL expression is invalid
- Custom SQL fields cannot be parsed as a single SQL statement
- Custom SQL fields cannot contain set operations.
- Metric '%(metric)s' does not exist
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/6e00e8430afb00ad.
Report an issue: GitHub.