HumanSignal/label-studio · error · ValidationError

load_tasks: No tasks added

Error message

load_tasks: No tasks added

What it means

ValidationError raised by load_tasks_for_async_import in label_studio/data_import/uploader.py. After confirming the payload is a list, it must be non-empty; an empty list means there is nothing to import, so the async import fails with 'load_tasks: No tasks added'.

Source

Thrown at label_studio/data_import/uploader.py:239

                found_formats,
                tasks,
                file_upload_ids,
                could_be_tasks_list,
            ) = tasks_from_url(file_upload_ids, project_import.project, user, url, could_be_tasks_list)
            if could_be_tasks_list:
                project_import.could_be_tasks_list = True
                project_import.save(update_fields=['could_be_tasks_list'])

    elif project_import.tasks:
        tasks = project_import.tasks

    # check is data root is list
    if not isinstance(tasks, list):
        raise ValidationError('load_tasks: Data root must be list')

    # empty tasks error
    if not tasks:
        raise ValidationError('load_tasks: No tasks added')

    check_max_task_number(tasks)
    return tasks, file_upload_ids, found_formats, list(data_keys)


def load_tasks_for_async_import_streaming(project_import, user, batch_size=1000):
    """Load tasks from different types of request.data / request.files saved in project_import model,
    yielding tasks in batches to reduce memory usage"""
    from django.conf import settings

    if not batch_size:
        batch_size = settings.IMPORT_BATCH_SIZE

    all_file_upload_ids = []
    all_found_formats = {}
    all_data_keys = set()

    if project_import.file_upload_ids:

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Check the source file/URL actually contains records before importing.
  2. Inspect the CSV: headers-only means no data rows — export with data or fix the delimiter/encoding.
  3. Fix upstream export filters that produced an empty dataset.
  4. Only call the import API once your payload has at least one task.

Example fix

// before
const tasks = await exportAll(); // []
await importTasks(tasks); // error

// after
if (tasks.length === 0) throw new Error('Nothing to export');
await importTasks(tasks);
Defensive patterns

Strategy: validation

Validate before calling

import json
payload = json.load(open(path))
if not isinstance(payload, list) or len(payload) == 0:
    raise ValueError('import payload is empty — export produced no tasks')
import_tasks(payload)

Type guard

def has_tasks(payload):
    return isinstance(payload, list) and len(payload) > 0

Try / catch

try:
    import_tasks(payload)
except ValidationError as e:
    if 'No tasks added' in str(e):
        log.error('source dataset empty — check export filters/CSV rows')
    else:
        raise

Prevention

When it happens

Trigger: async_import_background -> load_tasks_for_async_import with tasks == [] — e.g. an uploaded JSON file containing [], a CSV with only headers, a URL returning an empty array, or inline tasks submitted as [].

Common situations: Exporting zero rows from a filtered source; CSV where the parser drops all rows (encoding issues, wrong delimiter); a script uploading an empty placeholder before data is ready; URL import pointing at an empty result.

Related errors


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