HumanSignal/label-studio · error · ValidationError

data['{data_key}']={data_value} is of type '{type}', but the

Error message

data['{data_key}']={data_value} is of type '{type}', but the object tag {data_type} expects the following types: {expected_types}

What it means

After finding the required key, check_data validates its value's Python type against _DATA_TYPES, which maps each labeling-config object tag (Text, Image, HyperText, ...) to allowed types. This error means the key exists but its value's type is not allowed for the tag used in the config, e.g. a dict where Text expects str/int/float/list. Bracketed array tags (from Repeater, is_array=True) require a list.

Source

Thrown at label_studio/tasks/validation.py:85

            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,
                        expected_types=[e.__name__ for e in expected_types],
                    )
                )

        return data

    @staticmethod
    def check_data_and_root(project, data, dict_is_root=False):
        """Check data consistent and data is dict with task or dict['task'] is task

        :param project:
        :param data:

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Coerce the value to a type allowed by the tag (e.g. str(value) for Text, list for Repeater variables)
  2. Check _DATA_TYPES to see the accepted types for the tag used in your config
  3. If the config uses a bracketed/Repeater variable ($items), wrap the value in a list
  4. If you need richer payloads, use a tag that accepts dict (Table, TimeSeries) or upload the object as a file/reference

Example fix

// before
{'data': {'text': {'body': 'hello'}}}  # <Text value="$text"/>
// after
{'data': {'text': str({'body': 'hello'})}}  # or use a Table/TimeSeries tag that accepts dict
Defensive patterns

Strategy: type-guard

Validate before calling

_DATA_TYPES = {'Text': (str, int, float, list), 'Image': (str, list)}
for key, tag in project.data_types.items():
    key = key.split('[')[0]
    if key in data and not isinstance(data[key], tuple(_DATA_TYPES.get(tag, (str,)))):
        raise TypeError(f'{key} must match tag {tag}')

Type guard

def matches_tag(value, tag, is_array=False):
    expected = (list,) if is_array else tuple(_DATA_TYPES.get(tag, (str,)))
    return isinstance(value, expected)

Try / catch

try:
    import_tasks(tasks)
except ValidationError as e:
    m = re.search(r"data\['(.+?)'\].*tag (\w+)", str(e.detail[0]))
    if m:
        coerce_value(tasks, m.group(1), m.group(2))

Prevention

When it happens

Trigger: Config <Image value="$img"/> with data {'img': {'url': ...}} (dict, only str|list allowed); <Text value="$text"/> with {'text': {'a': 1}}; using $var inside a Repeater (e.g. $images) while the value is a single string instead of a list.

Common situations: Passing structured/nested objects where plain strings are expected; numbers-as-strings or booleans for Header/Text; giving a single item where the config's Repeater/bracket syntax expects an array; new tag types added to the config but not covered in _DATA_TYPES default to str-only.

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/3568a0295561d82a. Report an issue: GitHub.