{"record":{"id":"1e895dda431d4156","repo":"nicolargo/glances","slug":"self-class-name-object-has-no-key-it","errorCode":null,"errorMessage":"'{self.__class__.__name__}' object has no key '{item}'","messagePattern":"'(.+?)' object has no key '(.+?)'","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"glances/plugins/plugin/model.py","lineNumber":165,"sourceCode":"        return str(self.stats)\n\n    def __repr__(self):\n        \"\"\"Return the raw stats.\"\"\"\n        if isinstance(self.stats, list):\n            return str(list_to_dict(self.stats))\n        return str(self.stats)\n\n    def __getitem__(self, item):\n        \"\"\"Return the stats item.\"\"\"\n        if isinstance(self.stats, dict) and item in self.stats:\n            return self.stats[item]\n\n        if isinstance(self.stats, list):\n            ltd = list_to_dict(self.stats)\n            if item in ltd:\n                return ltd[item]\n\n        raise KeyError(f\"'{self.__class__.__name__}' object has no key '{item}'\")\n\n    def keys(self):\n        \"\"\"Return the keys of the stats.\"\"\"\n        if isinstance(self.stats, dict):\n            return listkeys(self.stats)\n        if isinstance(self.stats, list):\n            return listkeys(list_to_dict(self.stats))\n        return []\n\n    def get(self, item, default=None):\n        \"\"\"Return the stats item or default if not found.\"\"\"\n        try:\n            return self[item]\n        except KeyError:\n            return default\n\n    def get_init_value(self):\n        \"\"\"Return a copy of the init value.\"\"\"","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/nicolargo/glances/blob/a240d8dfb3105a38b5964357ec21768594b0e83e/glances/plugins/plugin/model.py#L147-L183","documentation":"KeyError raised by the plugin stats model's __getitem__ when code indexes a plugin instance with a key that is neither a key of its dict stats nor findable in list_to_dict(self.stats) for list-shaped stats. It is Glances' dict-style access protocol over the PluginModel in glances/plugins/plugin/model.py.","triggerScenarios":"plugin['nonexistent'] on a plugin whose stats dict lacks that key, or a key that doesn't match any item of the list form (list_to_dict maps list entries by their 'key'-like fields).","commonSituations":"Exporters or scripts assuming a field exists (e.g. stats['system'] on a plugin that only exposes 'user'/'iowait'); version changes renaming stat keys; iterating a plugin whose stats are still an empty list at startup.","solutions":["Inspect plugin.stats (or the REST API JSON for that plugin) to see actual available keys","Guard with 'key in plugin' — the model implements __contains__ via keys()/dict protocol — before indexing","Handle KeyError explicitly and skip/report the missing metric instead of crashing","Pin/align the Glances version whose stat key names your code expects"],"exampleFix":"# before\nval = plugin['user']\n# after\nval = plugin['user'] if 'user' in plugin else None","handlingStrategy":"type-guard","validationCode":"keys = plugin.keys() if hasattr(plugin, 'keys') else []\nvalue = plugin[item] if item in keys else None","typeGuard":"def stat_key_exists(plugin, key: str) -> bool:\n    keys = plugin.keys() if callable(getattr(plugin, 'keys', None)) else []\n    return key in keys","tryCatchPattern":"try:\n    val = plugin[item]\nexcept KeyError:\n    val = None  # metric absent in this plugin/version","preventionTips":["Use 'key in plugin' before indexing","Read plugin.stats or the REST JSON to learn available keys","Pin the Glances version your exporter targets"],"tags":["glances","plugin","key-error","stats"],"backgroundTag":"dict-key-missing","analyzedSha":"a240d8dfb3105a38b5964357ec21768594b0e83e","analyzedAt":"2026-08-27T19:15:19.178Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}