apache/superset · error · QueryObjectValidationError
Error in jinja expression in RLS filters: %(msg)s
Error message
Error in jinja expression in RLS filters: %(msg)s
What it means
QueryObjectValidationError wrapping a Jinja TemplateError or SupersetSyntaxErrorException raised while rendering row-level-security rule clauses in SqlaTable.get_sqla_row_level_filters (models.py:902). Each RLS rule's clause string is processed through the Jinja sandbox template processor before being embedded as a SQL predicate; malformed template syntax or disallowed sandbox constructs abort the query.
Source
Thrown at superset/connectors/sqla/models.py:902
filter_groups[filter_.group_key].append(clause)
else:
all_filters.append(clause)
if is_feature_enabled("EMBEDDED_SUPERSET"):
for rule in security_manager.get_guest_rls_filters(self):
if not include_global_guest_rls and not rule.get("dataset"):
continue
clause = self.text(
f"({template_processor.process_template(rule['clause'])})"
)
all_filters.append(clause)
grouped_filters = [or_(*clauses) for clauses in filter_groups.values()]
all_filters.extend(grouped_filters)
return all_filters
except (TemplateError, SupersetSyntaxErrorException) as ex:
msg = getattr(ex, "message", str(ex))
raise QueryObjectValidationError(
_(
"Error in jinja expression in RLS filters: %(msg)s",
msg=msg,
)
) from ex
class AnnotationDatasource(BaseDatasource):
"""Dummy object so we can query annotations using 'Viz' objects just like
regular datasources.
"""
cache_timeout = 0
changed_on = None
type = "annotation"
column_names = [
"created_on",
"changed_on",View on GitHub (pinned to f4587218dd)
Solutions
- Open Settings > Row Level Security, locate the failing rule for the dataset/roles, and fix the Jinja in its clause (test it separately in Explore with the same macros).
- Only use macros guaranteed in the query context (filter_values, url_param, current_username, etc.) and guard with default filters: {{ filter_values('x') | default([], true) }}.
- Check Superset logs for the underlying message (%(msg)s) — it names the exact template line/error.
- If the rule is not needed for the affected roles, remove the group/role from the rule's GroupKey so it stops applying.
Example fix
-- before (RLS clause)
country = '{{ filter_values('country') }}'
-- after (guard against undefined/empty and malformed Jinja)
country IN ({{ "'" ~ filter_values('country') | join("','") ~ "'" if filter_values('country') else "country" }}) Defensive patterns
Strategy: try-catch
Validate before calling
from jinja2.sandbox import SandboxedEnvironment
def rls_clause_renders(clause: str) -> bool:
env = SandboxedEnvironment()
try:
env.from_string(clause).render({})
return True
except Exception:
return False Try / catch
from superset.exceptions import QueryObjectValidationError
try:
df = query_context.get_df()
except QueryObjectValidationError as ex:
if "RLS filters" in str(ex):
# surface to admins: an RLS rule is broken, not the chart
notify_admins(f"Broken RLS rule: {ex}")
raise Prevention
- Lint RLS clauses with a Jinja sandbox render in CI before saving rules.
- Only use macros guaranteed available in RLS context; default-guard everything.
- Keep RLS clause edits behind review; a typo breaks every query for affected roles.
When it happens
Trigger: A dataset with an RLS rule (regular or dataset-scoped) whose clause contains invalid Jinja (e.g. unclosed {{, undefined filter, a blocked filter like {{ subprocess }}), executed whenever a query runs against a table for which the RLS rule applies to the current user's roles.
Common situations: Admin edits an RLS clause and introduces a typo; Jinja context differs between Explore and SQL Lab so macros valid elsewhere are undefined under RLS; copying a clause from a dashboard filter that references unavailable variables; upgrades that tighten the Jinja sandbox.
Related errors
- security_error
- Data URI is not allowed.
- Error in jinja expression in column expression: %(msg)s
- Error in jinja expression in datetime column: %(msg)s
- Error in jinja expression in metric expression: %(msg)s
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/d7dee27ae435ceb8.
Report an issue: GitHub.