{"record":{"id":"19e940f72ec7d872","repo":"nicolargo/glances","slug":"cannot-get-item-item-for-key-key-in-plugin-pl","errorCode":null,"errorMessage":"Cannot get item {item} for key {key} in plugin {plugin} ({str(e)})","messagePattern":"Cannot get item (.+?) for key (.+?) in plugin (.+?) \\((.+?)\\)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"glances/outputs/glances_restful_api.py","lineNumber":1147,"sourceCode":"    def _api_key(self, plugin: str, item: str, key: str):\n        \"\"\"Glances API RESTful implementation.\n\n        Return the JSON representation of  plugin/item/key\n        HTTP/200 if OK\n        HTTP/400 if plugin is not found\n        HTTP/404 if others error\n        \"\"\"\n        self._check_if_plugin_available(plugin)\n\n        # Update the stat\n        self.__update_stats(get_plugin_dependencies(plugin))\n\n        try:\n            # Get the RAW value of the stat views\n            # TODO in #3211: use a non existing (to be created) get_export_key instead but break API\n            ret = self.stats.get_plugin(plugin).get_raw_stats_key(item, key)\n        except Exception as e:\n            raise HTTPException(\n                status.HTTP_404_NOT_FOUND,\n                f\"Cannot get item {item} for key {key} in plugin {plugin} ({str(e)})\",\n            )\n\n        return GlancesJSONResponse(ret)\n\n    def _api_item_views(self, plugin: str, item: str):\n        \"\"\"Glances API RESTful implementation.\n\n        Return the JSON view representation of the couple plugin/item\n        HTTP/200 if OK\n        HTTP/400 if plugin is not found\n        HTTP/404 if others error\n        \"\"\"\n        self._check_if_plugin_available(plugin)\n\n        # Update the stat\n        self.__update_stats(get_plugin_dependencies(plugin))","sourceCodeStart":1129,"sourceCodeEnd":1165,"githubUrl":"https://github.com/nicolargo/glances/blob/a240d8dfb3105a38b5964357ec21768594b0e83e/glances/outputs/glances_restful_api.py#L1129-L1165","documentation":"Raised when get_raw_stats_key(item, key) fails on the nested key endpoint, returned as HTTP 404. This drills into list-of-dict stats (e.g., a specific NIC inside network stats); failure means the item or the inner key lookup raised — typically a missing key inside a dict-valued stat.","triggerScenarios":"GET /api/4/<plugin>/<item>/<key> with a bad item or key, e.g. /api/4/network/interface_name/tx/typo, or when the item is a scalar with no inner keys.","commonSituations":"Iterating keys discovered from a different glances version, or assuming all items are dict/list-of-dict when some are scalars.","solutions":["GET /api/4/<plugin>/<item> first and use exact inner key names","Confirm the item actually contains dict values (not a scalar)","Retry after a stats refresh if the item list can vary over time"],"exampleFix":"// before\nGET /api/4/network/eth0/speed // 404\n// after\nGET /api/4/network           // see structure: [{interface_name, speed, ...}]\nGET /api/4/network/interface_name/eth0","handlingStrategy":"validation","validationCode":"data = httpx.get(f'{BASE}/api/4/{plugin}/{item}').json()\nassert isinstance(data, (dict, list)), 'item has no nested keys'","typeGuard":"def has_inner_keys(data) -> bool:\n    return isinstance(data, dict) or (isinstance(data, list) and data and isinstance(data[0], dict))","tryCatchPattern":"try:\n    val = httpx.get(f'{BASE}/api/4/{plugin}/{item}/{key}').json()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404:\n        val = None\n    else:\n        raise","preventionTips":["Inspect the item's structure before drilling into keys","Re-discover dynamic keys (interface names, PIDs) each poll"],"tags":["glances","rest-api","http-404","nested-key","keyerror"],"backgroundTag":"http-404-resource-not-found","analyzedSha":"a240d8dfb3105a38b5964357ec21768594b0e83e","analyzedAt":"2026-08-27T19:15:19.178Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}