apache/superset · error · ValueError

Invalid filter: column '%s' does not exist on %s

Error message

Invalid filter: column '%s' does not exist on %s

What it means

Raised by BaseDAO.apply_column_operators() (superset/daos/base.py) when a ColumnOperator in the filters list references a column name that is empty or not an attribute of the DAO's model class (hasattr check). It is a ValueError; the same message is logged at error level first. Relationship names ARE valid here — only unknown attributes fail.

Source

Thrown at superset/daos/base.py:613

        cls, query: Any, column_operators: Optional[List[ColumnOperator]] = None
    ) -> Any:
        """
        Apply column operators (list of ColumnOperator) to the query using
        ColumnOperatorEnum logic. Raises ValueError if a filter references a
        non-existent column.
        """
        if not column_operators:
            return query
        for c in column_operators:
            if not isinstance(c, ColumnOperator):
                continue
            col, opr, value = c.col, c.opr, c.value
            if not col or not hasattr(cls.model_cls, col):
                model_name = cls.model_cls.__name__ if cls.model_cls else "Unknown"
                logging.error(
                    "Invalid filter: column '%s' does not exist on %s", col, model_name
                )
                raise ValueError(
                    "Invalid filter: column '%s' does not exist on %s"
                    % (col, model_name)
                )
            column = getattr(cls.model_cls, col)
            try:
                operator_enum = ColumnOperatorEnum(opr)
                # Relationship attributes (many-to-many or one-to-many)
                # can't be compared directly with scalar operators —
                # SQLAlchemy needs `.any(...)`. Detect the collection
                # case and dispatch to the related model's primary key
                # column. This lets callers use the natural shapes
                # `{col: "<relationship>", opr: "eq", value: <id>}` or
                # `{opr: "in", value: [<id>, ...]}` etc. to find rows
                # whose related collection contains those id(s).
                is_collection_relationship = (
                    hasattr(column, "property")
                    and isinstance(column.property, RelationshipProperty)
                    and column.property.uselist

View on GitHub (pinned to f4587218dd)

Solutions

  1. Call the resource's `/filters` endpoint (or DAO.get_filterable_columns_and_operators()) to list valid column names, then correct the filter's `col`.
  2. Check the model class for the DAO you're calling (Slice for charts, Dashboard, SqlaTable for datasets) and use the exact SQLAlchemy attribute name.
  3. Drop the filter entirely if it was speculative.

Example fix

# before
ChartDAO.find(query=", filters=[{"col": "owners", "opr": "eq", "value": 1}])
# (Slice has no `owners` attribute)

# after
ChartDAO.find(query=", filters=[{"col": "created_by_fk", "opr": "eq", "value": 1}])
Defensive patterns

Strategy: validation

Validate before calling

def valid_filter_cols(dao_cls, filters):
    return all(
        c.get("col") and hasattr(dao_cls.model_cls, c["col"])
        for c in (filters or [])
    )

Type guard

from superset.daos.filter import ColumnOperator

def is_known_column(model_cls, col: str | None) -> bool:
    return bool(col) and hasattr(model_cls, col)

Try / catch

try:
    ChartDAO.find(query=", filters=filters)
except ValueError as ex:
    if 'does not exist on' in str(ex):
        # drop bad filters, re-fetch valid columns, retry once
        ...

Prevention

When it happens

Trigger: Calling a DAO list/find API (e.g. ChartDAO.find, DashboardDAO.find) or the REST /api/v1/* resource with `filters=[{"col": "nonexistent", "opr": "eq", "value": 1}]`; a typo'd column name; using a column that exists on a different model than the DAO targets; col omitted/None.

Common situations: API clients built against an older Superset schema sending a column renamed since; MCP/tooling that guesses filter columns; passing an output/serialized field name (e.g. 'created_by_name') instead of the mapped model attribute.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/c738379006f0b0cc. Report an issue: GitHub.