HumanSignal/label-studio · error · ValidationError
Invalid or missing serializer class
Error message
Invalid or missing serializer class
What it means
validate_storage_instance raises ValidationError when the passed serializer_class is None/empty or lacks a Meta attribute, meaning the storage endpoint was wired with an unknown or wrong storage type before any DB lookup happens.
Source
Thrown at label_studio/io_storages/functions.py:38
Preload and prepare a storage instance from request data.
This function handles the common logic for loading existing storage instances
or creating new ones from request data, including permission checks and
serializer validation.
Args:
request: The HTTP request containing storage data
serializer_class: The serializer class to use for validation
Returns:
The prepared storage instance
Raises:
PermissionDenied: If user doesn't have permission to access the storage
ValidationError: If serializer validation fails
"""
if not serializer_class or not hasattr(serializer_class, 'Meta'):
raise ValidationError('Invalid or missing serializer class')
storage_id = request.data.get('id')
instance = None
if storage_id:
instance = get_object_or_404(serializer_class.Meta.model.objects.all(), pk=storage_id)
if not instance.has_permission(request.user):
raise PermissionDenied()
# combine instance fields with request.data
serializer = serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
# if storage exists, we have to use instance from DB,
# because instance from serializer won't have credentials, they were popped intentionally
if instance:
instance = serializer.update(instance, serializer.validated_data)
else:View on GitHub (pinned to 0b49e9b539)
Solutions
- Ensure the storage type in the request maps to a registered serializer in io_storages/functions.py get_storage_list()
- Verify the custom storage's serializer subclasses ImportStorageSerializer/ExportStorageSerializer and defines Meta with model
- If you hit this from a custom view, pass the correct serializer_class to validate_storage_instance
- After adding a new storage type, restart the server so the registry is rebuilt
Example fix
// before (custom storage not registered)
class MyStorageSerializer: # no Meta
class Meta: pass # missing model
// after
from label_studio.io_storages.serializers import ImportStorageSerializer
class MyStorageSerializer(ImportStorageSerializer):
class Meta:
model = MyStorage
fields = '__all__' Defensive patterns
Strategy: validation
Validate before calling
def serializer_is_usable(serializer_class):
return bool(serializer_class) and hasattr(serializer_class, 'Meta') and getattr(serializer_class.Meta, 'model', None) is not None Type guard
def is_drf_serializer(cls):
return isinstance(cls, type) and hasattr(cls, 'Meta') and hasattr(cls.Meta, 'model') Try / catch
from rest_framework.exceptions import ValidationError
try:
instance = validate_storage_instance(request, serializer_class)
except ValidationError as e:
logger.error('Bad storage serializer wiring: %s', e.detail) Prevention
- Register every custom storage serializer in get_storage_list()
- Subclass ImportStorageSerializer/ExportStorageSerializer and define Meta.model
- Send a supported storage type in the API path
- Restart the server after changing the storage registry
When it happens
Trigger: Calling create() (the storage API view) for a storage type whose serializer class could not be resolved (get_storage_list mismatch, unsupported/removed storage type in the URL path, a coding error passing the wrong class).
Common situations: Registering a custom storage but forgetting to add its serializer to get_storage_list(); typos in storage type in the API request; a plugin/older storage type removed after an upgrade.
Related errors
- sample() does not accept arguments.
- random(min, max) requires two arguments.
- choices(values:list, weights:list) requires one or two argum
- replace(old_value, new_value) requires two arguments.
- Undefined expression, you can use: {add_data_field_examples}
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/e174dee7936128b5.
Report an issue: GitHub.