HumanSignal/label-studio · error · PermissionDenied
Action is not allowed for the current user: {action_id}
Error message
Action is not allowed for the current user: {action_id} What it means
Before executing a Data Manager action, Label Studio invokes the configurable permission check (DATA_MANAGER_CHECK_ACTION_PERMISSION, default checks the action's required permissions for the user on the project). If the check fails, perform_action raises PermissionDenied with the action id. The action is registered but the current user is not allowed to run it on that project.
Source
Thrown at label_studio/data_manager/actions/__init__.py:168
logger.info(e)
continue
for action in module_actions:
register_action(**action)
logger.debug('Action registered: ' + str(action['entry_point'].__name__))
def perform_action(action_id, project, queryset, user, **kwargs):
"""Perform action using entry point from actions"""
if action_id not in settings.DATA_MANAGER_ACTIONS:
raise ValidationError("Can't find '" + action_id + "' in registered actions")
action = settings.DATA_MANAGER_ACTIONS[action_id]
check_permission = load_func(settings.DATA_MANAGER_CHECK_ACTION_PERMISSION)
# check user permissions for this action
if not check_permission(user, action, project):
raise PermissionDenied(f'Action is not allowed for the current user: {action["id"]}')
try:
result = action['entry_point'](project, queryset, **kwargs)
except Exception as e:
text = 'Error while perform action: ' + action_id + '\n' + tb.format_exc()
logger.error(text, extra={'sentry_skip': True})
raise e
return result
def get_action_form(action_id, project, user):
if action_id not in settings.DATA_MANAGER_ACTIONS:
raise ValidationError("Can't find '" + action_id + "' in registered actions")
action = settings.DATA_MANAGER_ACTIONS[action_id]
check_permission = load_func(settings.DATA_MANAGER_CHECK_ACTION_PERMISSION)
View on GitHub (pinned to 0b49e9b539)
Solutions
- Re-run the action with credentials of a user having the required role (owner/administrator) on the project
- Grant the user the necessary project role or permissions in the organization settings
- If using a custom DATA_MANAGER_CHECK_ACTION_PERMISSION, review its logic and the action's 'permissions' entry
Example fix
// before
requests.post(dm_action_url, headers=user_headers, ...) # annotator token
// after
admin_token = os.environ['LABEL_STUDIO_ADMIN_TOKEN']
requests.post(dm_action_url, headers={'Authorization': f'Token {admin_token}'}, ...) Defensive patterns
Strategy: try-catch
Validate before calling
user_role = get_current_user_project_role(project_id) # e.g. via /api/current-user/whoami or org API
if user_role not in ('owner', 'administrator', 'manager'):
raise PermissionError(f'User lacks role required for action {action_id}') Type guard
def can_perform(user, action, required_roles):
return user.get('role') in required_roles Try / catch
try:
perform_action(action_id)
except PermissionDenied:
logger.warning(f'Action {action_id} denied for current user; retrying with admin credentials')
perform_action_with_admin(action_id) Prevention
- Run automation with a service account holding the required project role
- Check the action's declared permissions before invoking it
- Keep org role assignments updated for users triggering actions
When it happens
Trigger: A non-privileged user (annotator/reviewer role) POSTs to /api/dm/actions for an action requiring e.g. project admin/owner permissions, such as delete_tasks.
Common situations: Automations or scripts using a personal token of a low-privileged user; role changes after org restructuring; frontend exposing actions the user cannot execute; custom permission function misconfigured.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Can't find '{action_id}' in registered actions
- Add or Update Columns is not enabled for this organization.
- sample() does not accept arguments.
- random(min, max) requires two arguments.
- choices(values:list, weights:list) requires one or two argum
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/b6b484fa565ebbb4.
Report an issue: GitHub.