{"record":{"id":"7b25a63b4ddd1ef2","repo":"apache/superset","slug":"error-in-jinja-expression-in-adhoc-column-msg-s","errorCode":null,"errorMessage":"Error in jinja expression in adhoc column: %(msg)s","messagePattern":"Error in jinja expression in adhoc column: (.+?)","errorType":"validation","errorClass":"QueryObjectValidationError","httpStatus":400,"severity":"error","filePath":"superset/connectors/sqla/models.py","lineNumber":1950,"sourceCode":"\n        return self.make_sqla_column_compatible(sqla_metric, label)\n\n    def _render_adhoc_expression_for_metadata_lookup(\n        self,\n        sql_expression: str,\n        template_processor: BaseTemplateProcessor | None,\n    ) -> str:\n        \"\"\"Render Jinja in *sql_expression* so the result can be matched against\n        column metadata.  Without this, a templated expression such as\n        ``{{ filter_values('x')[0] }}`` is passed raw to ``get_column``, never\n        matches, and falls back to ``literal_column`` — which breaks for virtual\n        datasets because the rendered name isn't present in the FROM subquery.\"\"\"\n        if not template_processor:\n            return sql_expression\n        try:\n            return template_processor.process_template(sql_expression)\n        except SupersetSyntaxErrorException as ex:\n            raise QueryObjectValidationError(\n                _(\n                    \"Error in jinja expression in adhoc column: %(msg)s\",\n                    msg=str(ex),\n                )\n            ) from ex\n\n    def adhoc_column_to_sqla(  # pylint: disable=too-many-locals\n        self,\n        col: AdhocColumn,\n        force_type_check: bool = False,\n        template_processor: BaseTemplateProcessor | None = None,\n    ) -> tuple[ColumnElement, utils.GenericDataType | None]:\n        \"\"\"\n        Turn an adhoc column into a sqlalchemy column.\n\n        :param col: Adhoc column definition\n        :param force_type_check: Should the column type be checked in the db.\n               This is needed to validate if a filter with an adhoc column","sourceCodeStart":1932,"sourceCodeEnd":1968,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/connectors/sqla/models.py#L1932-L1968","documentation":"QueryObjectValidationError raised in SqlTable._render_adhoc_expression_for_metadata_lookup (models.py:1950) when Jinja rendering of an adhoc column's sqlExpression fails with SupersetSyntaxErrorException. This helper renders templated adhoc column SQL so the result can be matched against column metadata before falling back to literal_column; rendering failures (syntax, sandbox, undefined) abort the query.","triggerScenarios":"A chart using an adhoc column (Custom SQL column in the groupby/dimension slot, e.g. CAST({{ col }} AS BIGINT) or filter_values-based expressions) whose Jinja fails to render — undefined runtime filters, malformed template, blocked filters.","commonSituations":"filter_values('x')[0] patterns in adhoc columns when chart context lacks that filter (reports, alerts, other dashboards); typos in template syntax; sandboxed Jinja rejecting previously allowed constructs after upgrade.","solutions":["Guard the Jinja so it renders in every context: {{ filter_values('x') | default(['fallback'], true) | first }}.","Fix template syntax errors reported in %(msg)s (str(ex) carries the Jinja error detail).","If no templating is needed, replace the adhoc column SQL with static SQL or a dataset calculated column."],"exampleFix":"// before (adhoc column)\n{ sqlExpression: \"CAST({{ filter_values('amt')[0] }} AS BIGINT)\" }\n\n// after\n{ sqlExpression: \"CAST({{ filter_values('amt') | default(['0'], true) | first }} AS BIGINT)\" }","handlingStrategy":"try-catch","validationCode":"from jinja2.sandbox import SandboxedEnvironment\n\ndef adhoc_column_renders(sql_expression: str) -> bool:\n    try:\n        SandboxedEnvironment().from_string(sql_expression).render({})\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"from superset.exceptions import QueryObjectValidationError\n\ntry:\n    col, generic_type = table.adhoc_column_to_sqla(adhoc_col, template_processor=processor)\nexcept QueryObjectValidationError as ex:\n    if \"adhoc column\" in str(ex):\n        report_bad_chart_expression(adhoc_col, ex)\n    raise","preventionTips":["Guard filter_values macros in adhoc columns with |default so they render headlessly.","Prefer dataset calculated columns for reusable templated expressions (easier to test centrally).","Add render checks for adhoc column SQL in chart-building test suites."],"tags":["jinja","adhoc-column","superset","validation"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}