HumanSignal/label-studio · error · ValidationError
Value must be a list
Error message
Value must be a list
What it means
DRF ValidationError from validate_string_list raised when the value is not a Python list (e.g. a comma-separated string, dict, or scalar). The validator checks type after the emptiness check.
Source
Thrown at label_studio/ml_models/models.py:27
from ml_model_providers.models import ModelProviderConnection, ModelProviders
from projects.models import Project
from rest_framework.exceptions import ValidationError
from tasks.models import Annotation, FailedPrediction, Prediction, PredictionMeta
logger = logging.getLogger(__name__)
# skills are partitions of projects (label config + input columns + output columns) into categories of labeling tasks
class SkillNames(models.TextChoices):
TEXT_CLASSIFICATION = 'TextClassification', _('TextClassification')
NAMED_ENTITY_RECOGNITION = 'NamedEntityRecognition', _('NamedEntityRecognition')
def validate_string_list(value):
if not value:
raise ValidationError('list should not be empty')
if not isinstance(value, list):
raise ValidationError('Value must be a list')
if not all(isinstance(item, str) for item in value):
raise ValidationError('All items in the list must be strings')
class ModelInterface(models.Model):
title = models.CharField(_('title'), max_length=500, null=False, blank=False, help_text='Model name')
description = models.TextField(_('description'), null=True, blank=True, help_text='Model description')
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, related_name='created_models', on_delete=models.SET_NULL, null=True
)
created_at = models.DateTimeField(_('created at'), auto_now_add=True)
updated_at = models.DateTimeField(_('updated at'), auto_now=True)
organization = models.ForeignKey(View on GitHub (pinned to 0b49e9b539)
Solutions
- Send the value as a JSON array, e.g. ["a","b"] instead of "a,b"
- Split strings client-side before submission
- Align the ML backend's returned interface format with the expected list schema
Example fix
// before
{"labels": "class_a,class_b"}
// after
{"labels": ["class_a", "class_b"]} Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(value, list):
if isinstance(value, str):
value = value.split(',') # coerce common string form Type guard
def is_str_list(v) -> bool:
return isinstance(v, list) Try / catch
try:
interface.full_clean()
except ValidationError as e:
if 'Value must be a list' in str(e):
value = [s.strip() for s in str(value).split(',')] Prevention
- Always serialize list fields as JSON arrays, not comma strings
- Fix JSON/YAML config parsing so lists stay lists
- Add client-side schema validation matching the validator rules
When it happens
Trigger: Submitting a ModelInterface field as a string like "a,b" or a JSON object instead of a JSON array when creating/updating an ML model interface.
Common situations: Sending comma-separated strings from clients; JSON schema mismatch between ML backend and Label Studio; YAML/JSON config parsing producing a dict instead of a list.
Related errors
- All items in the list must be strings
- list should not be empty
- Filter value must be a list for `is any of` / `is none of`.
- User filter values must be integer ids.
- annotation_ser.errors
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/389e929fee29cf4c.
Report an issue: GitHub.