HumanSignal/label-studio · error · ValidationError

"{data_key}" key is expected in task data

Error message

"{data_key}" key is expected in task data

What it means

check_data iterates over project.data_types (the keys derived from the labeling config, e.g. <Text value="$text"/>) and requires each named key (including dotted nested paths like 'row.text') to exist in the task's data dict. This error means a required config variable is missing from the submitted data. For dotted keys the lookup uses reduce(getitem, keys, data), so a KeyError from any nesting level produces this message.

Source

Thrown at label_studio/tasks/validation.py:73

    def check_data(project, data):
        """Validate data from task['data']"""
        if data is None:
            raise ValidationError('Task is empty (None)')

        replace_task_data_undefined_with_config_field(data, project)

        # iterate over data types from project
        for data_key, data_type in project.data_types.items():
            # get array name in case of Repeater tag
            is_array = '[' in data_key
            data_key = data_key.split('[')[0]

            if '.' in data_key:
                keys = data_key.split('.')
                try:
                    data_item = reduce(getitem, keys, data)
                except KeyError:
                    raise ValidationError('"{data_key}" key is expected in task data'.format(data_key=data_key))
            else:
                if data_key not in data:
                    raise ValidationError('"{data_key}" key is expected in task data'.format(data_key=data_key))
                data_item = data[data_key]

            if is_array:
                expected_types = (list,)
            else:
                expected_types = _DATA_TYPES.get(data_type, (str,))

            if not isinstance(data_item, tuple(expected_types)):
                raise ValidationError(
                    "data['{data_key}']={data_value} is of type '{type}', "
                    'but the object tag {data_type} expects the following types: {expected_types}'.format(
                        data_key=data_key,
                        data_value=data_item,
                        type=type(data_item).__name__,
                        data_type=data_type,

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Make the task data include every key named by $-references in the labeling config
  2. For dotted keys like data.row.text, provide the full nested object structure
  3. Align import source column/field names with the config variables, or change the config to match the data
  4. Temporarily inspect project.data_types to list the exact required keys

Example fix

// before
project.import_tasks([{'data': {'sentence': 'hello'}}])  # config: <Text value="$text"/>
// after
project.import_tasks([{'data': {'text': 'hello'}}])
Defensive patterns

Strategy: validation

Validate before calling

def check_keys(payload, data_types):
    for key in data_types:
        node = payload
        for part in key.split('[')[0].split('.'):
            if not isinstance(node, dict) or part not in node:
                raise ValueError(f'missing config key: {key}')
            node = node[part]

Type guard

def nested_has(data, dotted):
    node = data
    return all(isinstance(node, dict) and part in node and (node := node[part]) is not None for part in dotted.split('.'))

Try / catch

try:
    import_tasks(tasks)
except ValidationError as e:
    m = re.search(r'"(.+)" key is expected', str(e.detail[0]))
    if m:
        tasks = [add_missing_key(t, m.group(1)) for t in tasks]

Prevention

When it happens

Trigger: Importing a task whose data dict lacks the key referenced by the config, e.g. config uses $text but the payload is {'sentence': 'hi'}; or nested config value="data.row.text" where any intermediate key is absent (Task data {'data': {}}).

Common situations: Renaming a variable in the label config without updating import payloads; CSV column name mismatch (header 'Text' vs $text); nested JSON imports where an expected intermediate object is absent.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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