{"record":{"id":"a66c98728679056d","repo":"WZMIAOMIAO/deep-learning-for-image-processing","slug":"object-has-no-attribute-a66c98","errorCode":null,"errorMessage":"'{}' object has no attribute '{}'","messagePattern":"'(.+?)' object has no attribute '(.+?)'","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pytorch_object_detection/mask_rcnn/train_utils/distributed_utils.py","lineNumber":137,"sourceCode":"\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/blob/1ec3fe6f374fc9969973a61f819de25658595afa/pytorch_object_detection/mask_rcnn/train_utils/distributed_utils.py#L119-L155","documentation":"SmoothedValue/MetricLogger's __getattr__ looks up requested attributes in its meters dict and then its instance __dict__; if the attribute is in neither, it raises AttributeError. This typically surfaces as a typo of a loss/metric name logged via meter.meters keys.","triggerScenarios":"Accessing e.g. metric_logger.loss_mask when no 'loss_mask' meter was registered (update_losses never saw that key), or any attribute not added via meters.update/track.","commonSituations":"Accessing a loss key not produced by the model (name mismatch between model output dict and logger); reading stats before the first iteration; typos in attribute names.","solutions":["Check metric_logger.meters keys (print them) and use an existing name","Ensure the model's loss_dict keys are registered via metric_logger.update(loss_dict) before access","Use hasattr(metric_logger, name) or metric_logger.meters.get(name) for optional metrics"],"exampleFix":"// before\navg_mask_loss = metric_logger.loss_mask.global_avg  # may not exist\n// after\nif \"loss_mask\" in metric_logger.meters:\n    avg_mask_loss = metric_logger.loss_mask.global_avg","handlingStrategy":"type-guard","validationCode":"name = 'loss_mask'\nif name in metric_logger.meters:\n    value = metric_logger.meters[name].global_avg\nelse:\n    logger.warning(f'meter {name} not registered')","typeGuard":"def has_meter(logger_obj, name):\n    return name in getattr(logger_obj, 'meters', {})","tryCatchPattern":"try:\n    value = metric_logger.loss_mask.global_avg\nexcept AttributeError as e:\n    logger.warning(f'missing meter: {e}; available: {list(metric_logger.meters)}')\n    value = None","preventionTips":["Register every loss key via metric_logger.update(loss_dict) each iteration","Print metric_logger.meters keys when debugging","Use .meters.get(name) for optional metrics"],"tags":["python","metrics","attributeerror"],"backgroundTag":"attribute-not-found","analyzedSha":"1ec3fe6f374fc9969973a61f819de25658595afa","analyzedAt":"2026-08-30T09:19:11.901Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}