{"record":{"id":"b935872e0f569c24","repo":"nicolargo/glances","slug":"cannot-get-item-item-in-plugin-plugin-str-e","errorCode":null,"errorMessage":"Cannot get item {item} in plugin {plugin} ({str(e)})","messagePattern":"Cannot get item (.+?) in plugin (.+?) \\((.+?)\\)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"glances/outputs/glances_restful_api.py","lineNumber":1122,"sourceCode":"    def _api_item(self, plugin: str, item: str):\n        \"\"\"Glances API RESTful implementation.\n\n        Return the JSON 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))\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_item instead but break API\n            ret = self.stats.get_plugin(plugin).get_raw_stats_item(item)\n        except Exception as e:\n            raise HTTPException(\n                status.HTTP_404_NOT_FOUND,\n                f\"Cannot get item {item} in plugin {plugin} ({str(e)})\",\n            )\n\n        return GlancesJSONResponse(ret)\n\n    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))","sourceCodeStart":1104,"sourceCodeEnd":1140,"githubUrl":"https://github.com/nicolargo/glances/blob/a240d8dfb3105a38b5964357ec21768594b0e83e/glances/outputs/glances_restful_api.py#L1104-L1140","documentation":"Raised when get_raw_stats_item(item) fails, returned as HTTP 404. The plugin is known but the requested item could not be extracted — most often because the item name does not exist in the plugin's stats dict (KeyError) or the stats are not yet populated.","triggerScenarios":"GET /api/4/<plugin>/<item> with a nonexistent field name, e.g. /api/4/cpu/nonexistent, or querying an item before the first stats refresh completes.","commonSituations":"Clients using field names from older/newer glances versions (item names change across releases), or racing server startup.","solutions":["GET /api/4/<plugin> once and use exact item keys from the response","Retry after the first refresh interval to rule out uninitialized stats","Upgrade glances or pin the client to the field names of the deployed version"],"exampleFix":"// before\nGET /api/4/cpu/total  // 404: item does not exist\n// after\nGET /api/4/cpu       // inspect keys, then\nGET /api/4/cpu/total_percent","handlingStrategy":"validation","validationCode":"keys = httpx.get(f'{BASE}/api/4/{plugin}').json().keys()  # or first element if list\nassert item in keys, f'{item} not in {list(keys)}'","typeGuard":"def item_exists(item: str, plugin_stats: dict) -> bool:\n    return isinstance(plugin_stats, dict) and item in plugin_stats","tryCatchPattern":"try:\n    val = httpx.get(f'{BASE}/api/4/{plugin}/{item}').json()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404:\n        val = None  # item absent this version/cycle\n    else:\n        raise","preventionTips":["Discover item names from /api/4/<plugin> at runtime instead of hardcoding","Handle 404 gracefully for version-dependent field names"],"tags":["glances","rest-api","http-404","item","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"}