apache/superset · error · ValueError
user_id is required for private tasks
Error message
user_id is required for private tasks
What it means
Raised by TaskDAO.create_task (superset/daos/tasks.py) when scope is TaskScope.PRIVATE but user_id is None. Private tasks are keyed and deduplicated per user (get_active_dedup_key includes user_id), so an anonymous private task cannot be deduplicated or scoped; the DAO enforces the invariant with a ValueError before building the dedup key. Scope accepts either the TaskScope enum or its string value and normalizes both, but the user_id requirement applies regardless.
Source
Thrown at superset/daos/tasks.py:137
already checked for existing tasks. Business logic (create vs join)
is handled by SubmitTaskCommand.
:param task_type: Type of task to create
:param task_key: Task identifier (required)
:param scope: Task scope (private/shared/system), defaults to private
:param user_id: User ID creating the task
:param payload: Optional user-defined context data (dict)
:param properties: Optional framework-managed runtime state (e.g., timeout)
:param kwargs: Additional task attributes (e.g., task_name)
:returns: Created Task instance
"""
# Handle both TaskScope enum and string values
scope_value = scope.value if isinstance(scope, TaskScope) else scope
scope_enum = scope if isinstance(scope, TaskScope) else TaskScope(scope)
# Validate user_id is required for private tasks
if scope_enum == TaskScope.PRIVATE and user_id is None:
raise ValueError("user_id is required for private tasks")
# Build dedup_key for active task
dedup_key = get_active_dedup_key(
scope=scope,
task_type=task_type,
task_key=task_key,
user_id=user_id,
)
# Note: properties is handled separately via update_properties()
task_data = {
"task_type": task_type,
"task_key": task_key,
"scope": scope_value,
"status": TaskStatus.PENDING.value,
"dedup_key": dedup_key,
**kwargs,
}View on GitHub (pinned to f4587218dd)
Solutions
- Pass user_id=get_user_id() (or the owning user's id) whenever creating a PRIVATE task.
- If the task is genuinely system-wide, use TaskScope.GLOBAL instead of PRIVATE.
- Validate scope/user_id pairing at the API boundary so callers get a 4xx, not a ValueError from the DAO.
- In celery contexts with no request, read the user from the trigger payload and pass it explicitly.
Example fix
# before
TaskDAO.create_task(scope=TaskScope.PRIVATE, task_type='alert', task_key=key) # ValueError
# after
TaskDAO.create_task(
scope=TaskScope.PRIVATE,
task_type='alert',
task_key=key,
user_id=get_user_id(), # required for PRIVATE scope
) Defensive patterns
Strategy: validation
Validate before calling
from superset.daos.task import TaskScope # adjust import path to actual enum home
from superset.utils.core import get_user_id
def validate_task_scope(scope: TaskScope, user_id: int | None) -> list[str]:
errors = []
if scope == TaskScope.PRIVATE and user_id is None:
errors.append('user_id is required for private tasks')
return errors Type guard
def is_valid_private_task(scope: TaskScope, user_id: int | None) -> TypeGuard[bool]:
return scope != TaskScope.PRIVATE or user_id is not None Try / catch
try:
task = TaskDAO.create_task(scope=scope, task_type=task_type, task_key=task_key, user_id=user_id)
except ValueError as err:
if 'private tasks' in str(err):
task = TaskDAO.create_task(scope=scope, task_type=task_type, task_key=task_key, user_id=get_user_id()) Prevention
- Always pass the triggering user's id when creating PRIVATE tasks, including in celery contexts.
- Enforce the scope/user_id pairing in API schemas so callers get 4xx instead of a DAO ValueError.
- Use GLOBAL scope only for genuinely system-wide tasks.
When it happens
Trigger: Calling TaskDAO.create_task(scope='PRIVATE', task_type=..., task_key=..., user_id=None); background/command code that starts private tasks without threading the requesting user through; defaulting user_id to None in a new integration instead of g.user.id.
Common situations: New notification/alert execution paths or custom schedulers adopting the tasks framework and forgetting user propagation; refactors that drop user_id from kwargs; calling task creation outside a request context where user_id must be passed explicitly rather than derived.
Related errors
- Task {task_uuid} is in progress but has not registered an ab
- Invalid filter: column '%s' does not exist on %s
- Operator '{operator_enum.value}' on relationship column '{co
- created_by_fk_or_editor only supports 'eq'; got '{c.opr}'
- created_by_fk_or_editor only supports 'eq'; got '{c.opr}'
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/f8f4ad6aaf67dc51.
Report an issue: GitHub.