HumanSignal/label-studio · error · TransitionValidationError

Transition validation failed for {self.transition_name}

Error message

Transition validation failed for {self.transition_name}

What it means

BaseTransition.prepare_and_validate raises TransitionValidationError when the transition's validate_transition(context) returns False (and validation was not skipped). It includes current and target state in the error details.

Source

Thrown at label_studio/fsm/transitions.py:309

        Args:
            context: The transition context

        Returns:
            Dictionary of transition data to be stored with the state record

        Raises:
            TransitionValidationError: If validation fails
        """
        # Set context for access during transition
        self.context = context

        # Update context with transition name
        context.transition_name = self.transition_name

        try:
            # Validate transition
            if not context.skip_validation and not self.validate_transition(context):
                raise TransitionValidationError(
                    f'Transition validation failed for {self.transition_name}',
                    {'current_state': context.current_state, 'target_state': context.target_state},
                )

            # Pre-transition hook
            self.pre_transition_hook(context)

            # Execute the transition logic
            transition_data = self.transition(context)

            return transition_data

        except Exception:
            # Clear context on error
            self.context = None
            raise

    def finalize(self, context: TransitionContext[EntityType, StateModelType], state_record: StateModelType) -> None:

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Inspect the error details dict {current_state, target_state} to see which state combination failed.
  2. Fix the entity's state (run prerequisite transitions) before this transition.
  3. Update validate_transition in the transition class if the rule is too strict for legitimate flows.
  4. Only pass skip_validation=True for trusted internal/admin paths, never for user-driven requests.

Example fix

// before
if not self.validate_transition(context):
    raise TransitionValidationError(f'Transition validation failed for {self.transition_name}', ...)
// after
if not self.validate_transition(context):
    logger.warning('validation failed: %s -> %s', context.current_state, context.target_state)
    raise TransitionValidationError(f'Transition validation failed for {self.transition_name}',
        {'current_state': context.current_state, 'target_state': context.target_state})
Defensive patterns

Strategy: try-catch

Validate before calling

ctx = build_context(entity)
if not transition.validate_transition(ctx):
    # precondition failed; handle before invoking prepare_and_validate
    ...

Try / catch

try:
    transition.prepare_and_validate(context)
except TransitionValidationError as e:
    details = e.details or {}
    logger.info('Transition %s rejected: %s -> %s', transition.transition_name,
                details.get('current_state'), details.get('target_state'))
    raise HTTPValidationError(str(e))

Prevention

When it happens

Trigger: Calling prepare_and_validate (directly or via execute_transition_with_state_manager) where validate_transition returns False — e.g. transition preconditions (permissions, state, payload) unmet. test_skip_validation_flag exercises the skip_validation bypass path.

Common situations: Custom transitions returning False for unsupported state combinations; entity in an unexpected state due to prior failed transitions; missing context fields (e.g. user) so validation logic bails out; skipping validation deliberately in tests with skip_validation=True.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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