apache/superset · error · ValidationError

Regular RLS filters require at least one subject.

Error message

Regular RLS filters require at least one subject.

What it means

ValidationError raised in CreateRLSRuleCommand.validate when filter_type equals RowLevelSecurityFilterType.REGULAR and the subjects list is empty — regular RLS filters must be bound to at least one user/role subject. (Base filter types are exempt.)

Source

Thrown at superset/commands/security/create.py:85

            .all()
        )
        if len(tables) != len(self._tables):
            raise DatasourceNotFoundValidationError()
        raise_for_datasource_access(tables)
        self._properties["tables"] = tables

        name = self._properties.get("name")
        if name and not RLSDAO.validate_uniqueness(name):
            raise ValidationError(
                {"name": [_("A rule with this name already exists.")]}
            )

        if (
            self._properties.get("filter_type")
            == RowLevelSecurityFilterType.REGULAR.value
            and not self._subjects
        ):
            raise ValidationError(
                {"subjects": ["Regular RLS filters require at least one subject."]}
            )

        if self._subjects:
            subjects = populate_subject_list(
                self._subjects,
                default_to_user=False,
            )
            self._properties["subjects"] = subjects

View on GitHub (pinned to f4587218dd)

Solutions

  1. Add at least one subject, e.g. {'subject_type': 'Role', 'subject': 'Public'} or a specific user/role
  2. If the clause must apply to all users regardless of role, consider a Base filter (filter_type='Base') which needs no subject
  3. Re-submit the POST with the populated subjects array

Example fix

# before
{'name': 'r', 'filter_type': 'Regular', 'tables': [1], 'subjects': []}

# after
{'name': 'r', 'filter_type': 'Regular', 'tables': [1],
 'subjects': [{'subject_type': 'Role', 'subject': 'Public'}]}
Defensive patterns

Strategy: validation

Validate before calling

if payload['filter_type'] == 'Regular':
    assert payload.get('subjects'), 'Regular RLS rules need >=1 subject'

Type guard

def rls_subjects_satisfied(payload: dict) -> bool:
    if payload.get('filter_type') != 'Regular':
        return True
    return bool(payload.get('subjects'))

Try / catch

from superset.commands.exceptions import ValidationError
try:
    CreateRLSRuleCommand(props).run()
except ValidationError as e:
    if 'subjects' in e.normalized_messages():
        props.setdefault('subjects', []).append({'subject_type': 'Role', 'subject': 'Public'})
        CreateRLSRuleCommand(props).run()

Prevention

When it happens

Trigger: POST /api/v1/rowlevelsecurity with filter_type='Regular' and an empty or missing 'subjects' array.

Common situations: Authors intending a rule that applies to everyone and omitting subjects (they should add the Public role or use a Base filter for shared clauses); form defaults that drop the subjects field.

Related errors


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