HumanSignal/label-studio · error · ValueError

If you use "annotations" field in the task, you must put "da

Error message

If you use "annotations" field in the task, you must put "data" field in the task too

What it means

add_task also requires that dicts carrying pre-made annotations include the task payload. A non-empty 'annotations' list without a 'data' key gives the annotations nothing to attach to, so a ValueError is raised and the task is not created.

Source

Thrown at label_studio/io_storages/base_models.py:511

        link_kwargs = asdict(link_object)
        data = link_kwargs.pop('task_data', None)

        allow_skip = data.get('allow_skip', True)

        # predictions
        predictions = data.get('predictions') or []
        if predictions:
            if 'data' not in data:
                raise ValueError(
                    'If you use "predictions" field in the task, you must put "data" field in the task too'
                )

        # annotations
        annotations = data.get('annotations') or []
        cancelled_annotations = 0
        if annotations:
            if 'data' not in data:
                raise ValueError(
                    'If you use "annotations" field in the task, you must put "data" field in the task too'
                )
            cancelled_annotations = len([a for a in annotations if a.get('was_cancelled', False)])

        storage_task_data_validator = load_func(getattr(settings, 'STORAGE_TASK_DATA_VALIDATOR', None))
        if storage_task_data_validator:
            storage_task_data_validator(project, data)

        if 'data' in data and isinstance(data['data'], dict):
            if data['data'] is not None:
                data = data['data']
            else:
                data.pop('data')

        with transaction.atomic():
            # Create task without skip_fsm (it's not a model field)
            task = Task(
                data=data,

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Include the 'data' field with the task payload in every dict that has 'annotations'.
  2. Remove the 'annotations' field if you intend a plain data import (annotations can be added later via the API).
  3. Validate the import file structure before calling add_task: data required whenever annotations or predictions exist.

Example fix

// before
task = {'annotations': [{'result': [...], 'was_cancelled': False}]}
storage.add_task(task)

// after
task = {'data': {'image': 's3://bucket/img.jpg'}, 'annotations': [{'result': [...], 'was_cancelled': False}]}
storage.add_task(task)
Defensive patterns

Strategy: validation

Validate before calling

def validate_task_payload(task: dict):
    if isinstance(task, dict) and task.get('annotations') and 'data' not in task:
        raise ValueError('Task payload with annotations must also include "data"')

Type guard

def is_valid_task_payload(task: dict) -> bool:
    return not (isinstance(task, dict) and task.get('annotations') and 'data' not in task)

Try / catch

try:
    storage.add_task(task)
except ValueError as e:
    if '"data" field in the task' in str(e):
        logger.error('Malformed task payload (missing data): %s', task)
    else:
        raise

Prevention

When it happens

Trigger: Calling add_task (or the storage sync / create_tasks paths) with a dict like {'annotations': [...]} that lacks 'data'.

Common situations: Re-importing exported annotations without their data payloads; importing completions from another tool; conversion scripts that copy only the annotations arrays.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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