HumanSignal/label-studio · error · ValidationError

Maximum task number is {settings.TASKS_MAX_NUMBER}, current

Error message

Maximum task number is {settings.TASKS_MAX_NUMBER}, current task number is {len(tasks)}

What it means

django.core.exceptions.ValidationError raised by check_max_task_number in label_studio/data_import/uploader.py. Label Studio enforces settings.TASKS_MAX_NUMBER as a hard cap on the number of tasks in a single import; if the task list exceeds that cap, import is rejected before any tasks are created. The limit protects the database and UI from unbounded imports.

Source

Thrown at label_studio/data_import/uploader.py:47


def csv_generate_header(file):
    """Generate column names for headless csv file"""
    file.seek(0)
    names = []
    line = file.readline()

    num_columns = len(line.split(b',' if isinstance(line, bytes) else ','))
    for i in range(num_columns):
        names.append('column' + str(i + 1))
    file.seek(0)
    return names


def check_max_task_number(tasks):
    # max tasks
    if len(tasks) > settings.TASKS_MAX_NUMBER:
        raise ValidationError(
            f'Maximum task number is {settings.TASKS_MAX_NUMBER}, current task number is {len(tasks)}'
        )


def check_tasks_max_file_size(value):
    if value >= settings.TASKS_MAX_FILE_SIZE:
        raise ValidationError(
            f'Maximum total size of all files is {settings.TASKS_MAX_FILE_SIZE} bytes, current size is {value} bytes'
        )


def check_extensions(files):
    for filename, file_obj in files.items():
        _, ext = os.path.splitext(file_obj.name)
        if ext.lower() not in settings.SUPPORTED_EXTENSIONS:
            raise ValidationError(f'{ext} extension is not supported')

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Raise the limit: set TASKS_MAX_NUMBER (e.g. export TASKS_MAX_NUMBER=1000000) in the Label Studio environment and restart.
  2. Split the import into multiple smaller batches, each under settings.TASKS_MAX_NUMBER tasks.
  3. Use the storage-sync import path (S3/GCS/Azure/Redis) or load_tasks_for_async_import_streaming for very large datasets instead of one-shot import.
  4. If importing via API, check the dataset row count against the server's limit before calling.

Example fix

// before (one-shot import of 50000 tasks)
requests.post(url + '/api/projects/1/import', json={'tasks': big_tasks})

// after (batched)
for i in range(0, len(big_tasks), 10000):
    requests.post(url + '/api/projects/1/import', json={'tasks': big_tasks[i:i+10000]})
Defensive patterns

Strategy: validation

Validate before calling

import os, requests
MAX = int(os.environ.get('TASKS_MAX_NUMBER', 100))
if len(tasks) > MAX:
    raise ValueError(f'{len(tasks)} tasks exceeds limit {MAX}; batch or raise TASKS_MAX_NUMBER')
requests.post(api + f'/projects/{pid}/import', json={'tasks': tasks})

Try / catch

try:
    import_tasks(tasks)
except ValidationError as e:
    if 'Maximum task number' in str(e):
        batch_import(tasks, size=MAX)  # split and retry per batch
    else:
        raise

Prevention

When it happens

Trigger: Calling load_tasks / load_tasks_for_async_import / load_tasks_for_async_import_streaming with a tasks list whose len(tasks) > settings.TASKS_MAX_NUMBER (default 100 in Label Studio). Typical via POST to the /api/projects/{id}/import endpoint with a large JSON/CSV file or inline tasks array.

Common situations: Bulk-importing a dataset larger than the configured limit; a fresh install keeping the low default TASKS_MAX_NUMBER; a script exporting from another tool and piping tens of thousands of rows straight into one import call; environment variable TASKS_MAX_NUMBER set lower than expected (e.g. set to a small value or a non-numeric that clamps).

Related errors


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