PaddlePaddle/PaddleOCR · error · ValueError

Cannot set key/value for {element}. It needs to be a tuple (

Error message

Cannot set key/value for {element}. It needs to be a tuple (key, value).

What it means

This head ships an HF-style ModelOutput dataclass. When constructed from an iterator, each element must be a (key: str, value) tuple so it can be setattr'd; the first element may instead match the first declared field, but any other non-tuple element raises this ValueError.

Source

Thrown at ppocr/modeling/heads/rec_unimernet_head.py:90

                first_field_iterator = True
            else:
                try:
                    iterator = iter(first_field)
                    first_field_iterator = True
                except TypeError:
                    first_field_iterator = False

            if first_field_iterator:
                for idx, element in enumerate(iterator):
                    if (
                        not isinstance(element, (list, tuple))
                        or not len(element) == 2
                        or not isinstance(element[0], str)
                    ):
                        if idx == 0:
                            self[class_fields[0].name] = first_field
                        else:
                            raise ValueError(
                                f"Cannot set key/value for {element}. It needs to be a tuple (key, value)."
                            )
                        break
                    setattr(self, element[0], element[1])
                    if element[1] is not None:
                        self[element[0]] = element[1]
            elif first_field is not None:
                self[class_fields[0].name] = first_field
        else:
            for field in class_fields:
                v = getattr(self, field.name)
                if v is not None:
                    self[field.name] = v

    def __delitem__(self, *args, **kwargs):
        raise Exception(
            f"You cannot use ``__delitem__`` on a {self.__class__.__name__} instance."
        )

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Pass keyword arguments (ModelOutput(loss=loss, logits=logits)) — the safest form
  2. If using an iterator, ensure every element is a (str_key, value) tuple: ModelOutput(zip(keys, values)) with keys all strings
  3. Convert foreign outputs via its dict(): ModelOutput(**other_output.to_dict()) or iterate items()

Example fix

# before
out = ModelOutput([loss, logits])
# after
out = ModelOutput(loss=loss, logits=logits)
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_output_init(items):
    for el in items:
        if not (isinstance(el, (list, tuple)) and len(el) == 2 and isinstance(el[0], str)):
            raise ValueError(f'ModelOutput iterator items must be (str, value) tuples, got {el!r}')
    return items
# ModelOutput(valid_output_init(list(zip(keys, values))))

Type guard

def is_kv_tuple(el) -> bool:
    return isinstance(el, (list, tuple)) and len(el) == 2 and isinstance(el[0], str)

Try / catch

try:
    out = ModelOutput(items)
except ValueError as e:
    if 'Cannot set key/value' in str(e):
        out = ModelOutput(**dict(zip(keys, values)))
    else:
        raise

Prevention

When it happens

Trigger: Calling ModelOutput([...]) with a list whose elements are not 2-tuples starting with a string — e.g. ModelOutput([loss, logits]), ModelOutput([('a',1), (2,'x')]), or zip artifacts where keys were dropped.

Common situations: Refactoring output construction in a custom head/loss and passing raw tensors in a list; porting HF utility code that assumed dict(zip(keys, values)); constructing from another model's outputs tuple directly.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/9f421ad152d183fe. Report an issue: GitHub.