{"record":{"id":"6cd5d6e7ada430ea","repo":"apache/superset","slug":"ex-errors-0","errorCode":null,"errorMessage":"ex.errors[0]","messagePattern":"ex\\.errors\\[0\\]","errorType":"validation","errorClass":"ValidatorSQL400Error","httpStatus":400,"severity":"error","filePath":"superset/commands/database/validate_sql.py","lineNumber":112,"sourceCode":"            # process_template() renders Jinja2 templates and always returns a\n            # new string (does not mutate the input SQL). May raise\n            # SupersetSyntaxErrorException for template syntax errors or\n            # SupersetTemplateException for internal errors.\n            sql = template_processor.process_template(sql, **template_params)\n\n            timeout = app.config[\"SQLLAB_VALIDATION_TIMEOUT\"]\n            timeout_msg = f\"The query exceeded the {timeout} seconds timeout.\"\n            with utils.timeout(seconds=timeout, error_message=timeout_msg):\n                errors = self._validator.validate(sql, catalog, schema, self._model)\n            return [err.to_dict() for err in errors]\n        except SupersetSyntaxErrorException as ex:\n            # Template syntax errors (e.g., invalid Jinja2 syntax, undefined variables)\n            # These contain detailed error information including line numbers\n            logger.warning(\n                \"Template syntax error during SQL validation\",\n                extra={\"errors\": [err.message for err in ex.errors]},\n            )\n            raise ValidatorSQL400Error(ex.errors[0]) from ex\n        except SupersetTemplateException as ex:\n            # Internal template processing errors (e.g., recursion, unexpected failures)\n            logger.error(\n                \"Template processing error during SQL validation\", exc_info=True\n            )\n            superset_error = SupersetError(\n                message=__(\n                    \"Template processing failed: %(ex)s\",\n                    ex=str(ex),\n                ),\n                error_type=SupersetErrorType.GENERIC_COMMAND_ERROR,\n                level=ErrorLevel.ERROR,\n            )\n            raise ValidatorSQL400Error(superset_error) from ex\n        except Exception as ex:\n            logger.exception(ex)\n            superset_error = SupersetError(\n                message=__(","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/database/validate_sql.py#L94-L130","documentation":"At superset/commands/database/validate_sql.py:112 the handler for SupersetSyntaxErrorException passes ex.errors[0] into ValidatorSQL400Error. SupersetSyntaxErrorException is raised when Jinja template rendering of the SQL fails (invalid Jinja2 syntax, undefined variables) and it carries a list of SupersetError objects with details like line numbers. The indexer ex.errors[0] selects the first error to surface as an HTTP 400; if the exception was constructed with an empty errors list, this line itself raises IndexError.","triggerScenarios":"POST /api/v1/database/validate_sql with a `sql` payload containing malformed Jinja2 (e.g., unclosed {{, bad filter syntax) or references to undefined template variables; supplying `template_params` whose keys don't match the placeholders used in the SQL. Programmatically, raising SupersetSyntaxErrorException(errors=[]) makes line 112 fail with IndexError.","commonSituations":"Migrating SQL Lab queries with template markers from other tools; enabling Jinja templating (FEATURE_FLAGS) and using macros with typos; custom code in superset/jinja_context.py or custom template processors that raise SupersetSyntaxErrorException without an errors payload.","solutions":["Fix the Jinja2 syntax in the submitted SQL: balanced {{ }} / {% %}, valid filter names, and default values for variables (e.g., {{ my_var }} declared in template_params or with a |default filter).","Pass matching `template_params` in the request body for every variable referenced in the SQL.","If you raise SupersetSyntaxErrorException from custom template code, always construct it with at least one SupersetError so ex.errors[0] is defined.","Check the warning log ('Template syntax error during SQL validation') — it lists all error messages, which pinpoints the exact line."],"exampleFix":"{% raw %}\n-- before (undefined variable, bad filter)\nSELECT * FROM tbl WHERE d > {{ start_date | dataz }}\n\n-- after\nSELECT * FROM tbl WHERE d > '{{ start_date | default(\"2020-01-01\") }}'\n{% endraw %}","handlingStrategy":"try-catch","validationCode":"# Render the template client-side of the API before submitting for validation\nfrom superset.jinja_context import get_template_processor\n\ndef template_is_renderable(sql: str, database, template_params: dict) -> bool:\n    try:\n        get_template_processor(database=database).process_template(\n            sql, **(template_params or {})\n        )\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"from superset.commands.database.exceptions import (\n    ValidatorSQL400Error, ValidatorSQLError,\n)\ntry:\n    result = ValidatorSQLCommand(db_id, {\"sql\": sql, \"template_params\": params}).run()\nexcept ValidatorSQL400Error as ex:\n    # 400: syntax/template problem in the submitted SQL — show message, no retry\n    display(ex.error.message if ex.error else str(ex))\nexcept ValidatorSQLError as ex:\n    # 422: validator backend failure — safe to retry once\n    retry_once()","preventionTips":["Lint Jinja in SQL with a cheap render call before submitting to validate_sql.","Provide `template_params` for every variable referenced in the SQL, or use |default filters.","When raising SupersetSyntaxErrorException from custom template code, always include a non-empty errors list."],"tags":["sql-validation","jinja","templating","flask-api"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}