HumanSignal/label-studio · error · StateManagerError
Failed to transition state: {e}
Error message
Failed to transition state: {e} What it means
This is the catch-all wrap in transition_state: after validation passes, the actual state-record creation (state model save, cache update, transaction.on_commit work) raised an exception, which is re-raised as StateManagerError('Failed to transition state: ...') with full context logged (entity, transition, user, organization). The original exception is chained so the root cause is available.
Source
Thrown at label_studio/fsm/state_manager.py:427
organization_id = CurrentContext.get_organization_id()
logger.error(
'FSM: State transition failed',
extra={
'event': 'fsm.transition_state_failed',
'entity_type': entity._meta.label_lower,
'entity_id': entity.pk,
'from_state': current_state,
'to_state': new_state,
'error': str(e),
**{
'user_id': user.id if user else None,
'organization_id': organization_id if organization_id else None,
},
},
exc_info=True,
)
raise StateManagerError(f'Failed to transition state: {e}') from e
@classmethod
def get_state_history(cls, entity: Model) -> QuerySet[BaseState]:
"""
Get complete state history for an entity.
Args:
entity: Entity to get history for
Returns:
QuerySet of state records ordered by most recent first
"""
state_model = get_state_model_for_entity(entity)
if not state_model:
raise StateManagerError(
f'No state model registered for {entity._meta.model_name} when getting state history'
)
View on GitHub (pinned to 0b49e9b539)
Solutions
- Inspect server logs — the wrapped exception is logged with exc_info plus entity/transition/user context; fix the named root cause.
- Retry the transition after transient DB/Redis failures, ideally with idempotency: re-read current state and skip if the target state already applied.
- Reduce contention: avoid many concurrent transitions on the same entity; queue bulk state changes.
- Run pending migrations and verify the state table schema matches the installed code version.
Example fix
// before
StateManager.transition_state(task, 'completed', user=request.user) # deadlocks under load
// after
from fsm.state_manager import StateManagerError
for attempt in range(3):
try:
StateManager.transition_state(task, 'completed', user=request.user)
break
except StateManagerError:
if attempt == 2:
logger.exception('transition failed for task %s', task.pk)
raise
time.sleep(0.5 * (attempt + 1)) Defensive patterns
Strategy: retry
Validate before calling
from fsm.registry import get_state_model_for_entity from django.db import connection assert get_state_model_for_entity(entity) is not None connection.ensure_connection() # surface DB problems before attempting the transition
Type guard
def safe_to_transition(entity) -> bool:
from fsm.registry import get_state_model_for_entity
from django.db import connection
return get_state_model_for_entity(entity) is not None and connection.is_usable() Try / catch
from fsm.state_manager import StateManagerError
import time
for attempt in range(3):
try:
StateManager.transition_state(entity, new_state, user=user)
break
except StateManagerError as e:
if attempt == 2:
logger.exception('transition failed for %s', entity.pk)
raise
time.sleep(0.5 * (2 ** attempt)) Prevention
- Retry with exponential backoff for transient DB/cache failures; check current state first for idempotency
- Avoid many simultaneous transitions on the same entity to reduce lock contention
- Keep DB and Redis healthy and migrations applied; read the wrapped root cause in logs
When it happens
Trigger: Calling transition_state where the DB insert of the new state record fails (constraint violation, deadlocked/serialized transaction, connection drop), the cache update raises, or code inside the state model's record-creation path throws. Often seen under concurrent transitions on the same entity.
Common situations: Two workers transitioning the same task concurrently causing deadlocks or unique-constraint conflicts; Redis outage during the immediate cache update; long transactions holding locks during bulk operations; migration drift leaving required columns missing.
Related errors
- Error getting current state: {e}
- No state model found for {entity._meta.model_name} when gett
- No state model found for {entity._meta.model_name} when gett
- No state model found for {entity._meta.model_name} when tran
- No state model registered for {entity._meta.model_name} when
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/0fc731560758c948.
Report an issue: GitHub.