HumanSignal/label-studio · error · ValidationError

Can't find '{action_id}' in registered actions

Error message

Can't find '{action_id}' in registered actions

What it means

The Data Manager performs actions (e.g. delete tasks, predictions) by looking up action_id in settings.DATA_MANAGER_ACTIONS. If the requested id is not among the registered actions, perform_action raises this ValidationError naming the unknown id. It guards against typo'd or unavailable action identifiers.

Source

Thrown at label_studio/data_manager/actions/__init__.py:161

        name = path[0 : path.find('.py')]  # get only module name to read *.py and *.pyc
        try:
            module = import_module(f'{base_module}.{name}')
            if not hasattr(module, 'actions'):
                continue
            module_actions = module.actions
        except ModuleNotFoundError as e:
            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

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Check the exact action id against settings.DATA_MANAGER_KEYS / registered actions (e.g. 'delete_tasks', 'predictions_to_none')
  2. Register the custom action in DATA_MANAGER_ACTIONS or ensure the module registering it is imported at startup
  3. Upgrade/downgrade client code so it uses action ids supported by the running server version

Example fix

// before
POST /api/dm/actions?id=delete_all_tasks&project=1
// after
POST /api/dm/actions?id=delete_tasks&project=1
Defensive patterns

Strategy: try-catch

Validate before calling

import requests
actions = requests.get(f'{HOST}/api/dm/actions?project={project_id}', headers=headers).json()
known_ids = {a['id'] for a in actions}
assert action_id in known_ids, f'{action_id} not registered on this server'

Type guard

def is_registered_action(action_id, available_actions):
    return isinstance(action_id, str) and action_id in {a['id'] for a in available_actions}

Try / catch

try:
    perform_action(action_id)
except ValidationError as e:
    if "in registered actions" in str(e):
        logger.error(f'Unknown action {action_id}; check server version / settings.DATA_MANAGER_ACTIONS')
    else:
        raise

Prevention

When it happens

Trigger: POSTing to the Data Manager action endpoint with an action id string that is not registered — typos, actions from a different Label Studio version, or actions removed/renamed in configuration.

Common situations: Custom actions defined in a settings file that was not loaded (so DATA_MANAGER_ACTIONS lacks them); frontend/API version mismatch; renaming an action id in a fork without updating callers.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/d149fbd0ee311b94. Report an issue: GitHub.