HumanSignal/label-studio · error · ValidationError

data is empty

Error message

data is empty

What it means

TaskValidator.to_internal_value raises this when the payload is a list but contains zero items. An empty import batch would be a no-op, so the validator rejects it explicitly.

Source

Thrown at label_studio/tasks/validation.py:222

    def format_error(i, detail, item):
        if len(detail) == 1:
            code = (str(detail[0].code + ' ')) if detail[0].code != 'invalid' else ''
            return 'Error {code} at item {i}: {detail} :: {item}'.format(code=code, i=i, detail=detail[0], item=item)
        else:
            errors = ', '.join(detail)
            codes = str([d.code for d in detail])
            return 'Errors {codes} at item {i}: {errors} :: {item}'.format(codes=codes, i=i, errors=errors, item=item)

    def to_internal_value(self, data):
        """Body of run_validation for all data items"""
        if data is None:
            raise ValidationError('All tasks are empty (None)')

        if not isinstance(data, list):
            raise ValidationError('data is not a list')

        if len(data) == 0:
            raise ValidationError('data is empty')

        ret, errors = [], []
        self.annotation_count, self.prediction_count = 0, 0
        for i, item in enumerate(data):
            try:
                validated = self.validate(item)
            except ValidationError as exc:
                error = self.format_error(i, exc.detail, item)
                errors.append(error)
                # do not print to user too many errors
                if len(errors) >= 100:
                    errors[99] = '...'
                    break
            else:
                ret.append(validated)
                errors.append({})

                if 'annotations' in item:

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Check that your data source actually produced tasks before calling the import API
  2. Fix the upstream query/filter that yielded zero rows
  3. Skip the API call when the list is empty: if tasks: client.import_tasks(tasks)
  4. Validate the source file/CSV contains rows before import

Example fix

// before
client.import_tasks(id=id, tasks=rows)  # rows == []
// after
if not rows:
    raise ValueError("No rows to import")
client.import_tasks(id=id, tasks=rows)
Defensive patterns

Strategy: validation

Validate before calling

if not tasks:
    raise ValueError('Refusing to import: task list is empty')

Type guard

def is_nonempty_task_list(tasks):
    return isinstance(tasks, list) and len(tasks) > 0

Try / catch

try:
    client.import_tasks(id=project_id, tasks=tasks)
except LabelStudioError as e:
    if 'data is empty' in str(e):
        logging.warning('Import skipped: zero tasks collected upstream')
        return
    raise

Prevention

When it happens

Trigger: POSTing [] to the task import endpoint; passing a filtered/empty list from upstream code (e.g. tasks[:0], an empty query result); reading an empty-but-valid JSON file and sending its contents.

Common situations: Scripts whose upstream data extraction returned nothing (empty DB query, empty file, failed filter) but still called the import API; pagination logic ending with zero collected rows; users importing an empty CSV/JSON export.

Related errors


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