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.

Solutions

  1. Ensure the storage type in the request maps to a registered serializer in io_storages/functions.py get_storage_list()
  2. Verify the custom storage's serializer subclasses ImportStorageSerializer/ExportStorageSerializer and defines Meta with model
  3. If you hit this from a custom view, pass the correct serializer_class to validate_storage_instance
  4. 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

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


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

Appendix: 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)