HumanSignal/label-studio · error · ValidationError

transition_name: Unknown transition for this entity

Error message

transition_name: Unknown transition for this entity

What it means

The FSM transition POST endpoint validates the transition after resolving the entity: transition_registry.get_transition(entity_name, transition_name) must return a registered, manually-invokable transition class. If it is unknown (or, for ModelChangeTransition subclasses, configured with auto-triggers so it is not manual), DRF ValidationError({'transition_name': ['Unknown transition for this entity']}) is raised, producing HTTP 400.

Source

Thrown at label_studio/fsm/api.py:163

        'project': all_permissions.projects_change,
    }

    def post(self, request, *args, **kwargs):
        entity_name = kwargs['entity_name']
        if entity_name not in state_model_registry.get_all_models():
            raise NotFound()

        entity = self.get_entity()

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        transition_name = serializer.validated_data['transition_name']
        transition_data = serializer.validated_data.get('transition_data') or {}

        # Validate that transition is registered and manual (not auto-triggered)
        transition_class = transition_registry.get_transition(entity_name, transition_name)
        if not transition_class:
            raise ValidationError({'transition_name': ['Unknown transition for this entity']})

        # If it's a ModelChangeTransition and has any triggers configured, it's not manual
        if issubclass(transition_class, ModelChangeTransition):
            triggers_on_create = getattr(transition_class, '_triggers_on_create', False)
            triggers_on_update = getattr(transition_class, '_triggers_on_update', False)
            if triggers_on_create or triggers_on_update:
                raise ValidationError(
                    {'transition_name': ['Transition is auto-triggered and cannot be executed manually']}
                )

        # Execute transition
        StateManager = get_state_manager()
        try:
            state_record = StateManager.execute_transition(
                entity=entity,
                transition_name=transition_name,
                transition_data=transition_data,
                user=request.user,

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Use a transition_name that is registered for that exact entity — verify via transition_registry.get_transition(entity_name, name) or the API schema.
  2. Register the missing transition for the entity (and ensure it is manual, without auto-trigger flags if invoked via API).
  3. If the transition is auto-triggered, do not call it manually — let the model create/update trigger fire it.
  4. Fix typos/incorrect entity pairing in the client payload.
  5. Catch DRF ValidationError (400) client-side and list valid transitions for the user.

Example fix

// before
POST /api/fsm/task/42/transition {"transition_name": "complete_task"}  // not registered
// after
POST /api/fsm/task/42/transition {"transition_name": "mark_completed"}  // registered manual transition
Defensive patterns

Strategy: validation

Validate before calling

def transition_is_manual(entity_name: str, transition_name: str, registry) -> bool:
    from label_studio.fsm.state import ModelChangeTransition
    tc = registry.get_transition(entity_name, transition_name)
    if not tc:
        return False
    if issubclass(tc, ModelChangeTransition):
        return not (getattr(tc, '_triggers_on_create', False) or getattr(tc, '_triggers_on_update', False))
    return True

Try / catch

from rest_framework.exceptions import ValidationError
try:
    fire_transition(entity_name, entity_id, transition_name)
except ValidationError as e:
    if 'transition_name' in e.detail:
        valid = list_valid_transitions(entity_name)
        raise ValueError(f'{transition_name} invalid; valid: {valid}') from e
    raise

Prevention

When it happens

Trigger: POST transition with a transition_name that is not registered for the entity, a typo, a transition registered for a different entity, or an auto-triggered ModelChangeTransition (has _triggers_on_create/_triggers_on_update) being invoked manually.

Common situations: Frontend dropdowns out of sync with backend transition registrations; transitions registered under a different entity_name than requested; attempting to manually fire transitions that are meant to fire automatically on model create/update; version skew between services deploying new transition names.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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