PaddlePaddle/PaddleOCR · warning · Exception

You cannot use ``__delitem__`` on a {self.__class__.__name__

Error message

You cannot use ``__delitem__`` on a {self.__class__.__name__} instance.

What it means

The ModelOutput class in the UniMERNet head intentionally blocks dict-style destructive mutation; __delitem__ always raises so that users cannot silently delete declared dataclass fields and desync attribute/dict views.

Source

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

                            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."
        )

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

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

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

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Do not delete keys; build a new object with only the fields you want (e.g. construct another ModelOutput with the kept kwargs)
  2. If you need a mutable dict, convert first: d = output.to_dict() if available, or dict(output.items()), then delete from d
  3. Select fields via attribute access (output.logits) instead of removing the ones you don't want

Example fix

# before
del output['loss']
# after
lossless = {k: v for k, v in output.items() if k != 'loss'}
Defensive patterns

Strategy: type-guard

Validate before calling

def is_model_output(obj) -> bool:
    return type(obj).__name__ == 'ModelOutput' or hasattr(obj, 'to_tuple') and hasattr(obj, '__dataclass_fields__')

Type guard

def is_model_output(obj) -> bool:
    return hasattr(obj, '__dataclass_fields__') and hasattr(obj, 'to_tuple')

Try / catch

null  # intentional guard; branch on type instead of catching

Prevention

When it happens

Trigger: Calling del output['loss'] (or any __delitem__ use) on a ModelOutput instance returned by the head/loss computation.

Common situations: Treating ModelOutput like a plain dict in generic cleanup/aggregation code; copying dict-manipulation utilities over outputs; trying to strip fields before logging/serialization.

Related errors


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