{"record":{"id":"af6132f1a7451011","repo":"HumanSignal/label-studio","slug":"transition-validation-failed-for-self-transition","errorCode":null,"errorMessage":"Transition validation failed for {self.transition_name}","messagePattern":"Transition validation failed for (.+?)","errorType":"validation","errorClass":"TransitionValidationError","httpStatus":null,"severity":"error","filePath":"label_studio/fsm/transitions.py","lineNumber":309,"sourceCode":"        Args:\n            context: The transition context\n\n        Returns:\n            Dictionary of transition data to be stored with the state record\n\n        Raises:\n            TransitionValidationError: If validation fails\n        \"\"\"\n        # Set context for access during transition\n        self.context = context\n\n        # Update context with transition name\n        context.transition_name = self.transition_name\n\n        try:\n            # Validate transition\n            if not context.skip_validation and not self.validate_transition(context):\n                raise TransitionValidationError(\n                    f'Transition validation failed for {self.transition_name}',\n                    {'current_state': context.current_state, 'target_state': context.target_state},\n                )\n\n            # Pre-transition hook\n            self.pre_transition_hook(context)\n\n            # Execute the transition logic\n            transition_data = self.transition(context)\n\n            return transition_data\n\n        except Exception:\n            # Clear context on error\n            self.context = None\n            raise\n\n    def finalize(self, context: TransitionContext[EntityType, StateModelType], state_record: StateModelType) -> None:","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/fsm/transitions.py#L291-L327","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the error details dict {current_state, target_state} to see which state combination failed.","Fix the entity's state (run prerequisite transitions) before this transition.","Update validate_transition in the transition class if the rule is too strict for legitimate flows.","Only pass skip_validation=True for trusted internal/admin paths, never for user-driven requests."],"exampleFix":"// before\nif not self.validate_transition(context):\n    raise TransitionValidationError(f'Transition validation failed for {self.transition_name}', ...)\n// after\nif not self.validate_transition(context):\n    logger.warning('validation failed: %s -> %s', context.current_state, context.target_state)\n    raise TransitionValidationError(f'Transition validation failed for {self.transition_name}',\n        {'current_state': context.current_state, 'target_state': context.target_state})","handlingStrategy":"try-catch","validationCode":"ctx = build_context(entity)\nif not transition.validate_transition(ctx):\n    # precondition failed; handle before invoking prepare_and_validate\n    ...","typeGuard":null,"tryCatchPattern":"try:\n    transition.prepare_and_validate(context)\nexcept TransitionValidationError as e:\n    details = e.details or {}\n    logger.info('Transition %s rejected: %s -> %s', transition.transition_name,\n                details.get('current_state'), details.get('target_state'))\n    raise HTTPValidationError(str(e))","preventionTips":["Always surface the details dict (current/target state) to callers for diagnosis.","Document each transition's required preconditions next to validate_transition.","Avoid skip_validation=True in production code paths."],"tags":["fsm","validation","transition"],"backgroundTag":"invalid-state-transition","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}